近期热门
粉丝5
关注 0
获赞 13
Unity3d中人物控制脚本的实现

[U3D] Unity3d中人物控制脚本的实现

[复制链接]
12409 6 0 0 12年前 举报
本帖最后由 A你 于 2012-5-8 16:22 编辑

只是简单地实现了一下几个动作的调用,目前还在实验阶段,也不知道这样的调用方法可以一直延续下去不,当控制状态变得越来越多的时候,怎么样做到不互相影响,并且维护起来也是个问题,希望大家能一起考虑一下。也许可以借鉴一下已有项目的经验。

对D3D的空间几何知识是必要的,而这里要注意的是U3D提供了一个方法来判断是否与地面相碰撞,_grounded = (_flags & CollisionFlags.CollidedBelow) != 0;
其中CollisionFlags.CollidedBelow要想获得一个值,玩家的移动方向必须有朝向地面的方向向量分量。_grounded = (_flags & CollisionFlags.CollidedBelow) != 0;

为了在跳跃过程中更具有真实性,加入了重力加速度的概念,注意_gravity表示的是“重力速度”,也就是向下的一个向量分量。

// Require a character controller to be attached to the same game object
@script RequireComponent(CharacterController)
var _speed : float;
var _jumpspeed : float;
var _rotatespeed : float;
var _originalgravity : float;
var _gravity : float;
var _addgravity : float;
var _moveDirection: Vector3;
var _lastDirection: Vector3;
var _originalRotation : Quaternion;
var _flags;
var _grounded;
var _canjump;
var _animation;
var _run : AnimationClip;
var _idle : AnimationClip;
var _attack : AnimationClip;
var _jump : AnimationClip;
private var _controller : CharacterController;
enum PlayerState
{
STATE_READY = 0,
STATE_RUN = 1,
STATE_IDLE = 2,
STATE_ATTACK = 3,
STATE_JUMP = 4,
}
private var _playerstate : PlayerState;
function Start(){
_speed = 50F;
_jumpspeed = 40F;
_rotatespeed = 10F;

_originalgravity = 40;
_gravity = 40;
_addgravity = 3;

_canjump = true;

_moveDirection = Vector3.zero;
_lastDirection = Vector3.zero;
_originalRotation = new Quaternion(0f, 0f, 0f, 1f);

_grounded = true;
_animation = GetComponent(Animation);

_controller = GetComponent(CharacterController);

_playerstate = PlayerState.STATE_READY;

_moveDirection.y = -1; //给Y轴方向一个初始值,以使其可以与地面正确相撞
}
function Update () {
//模型的旋转(临时)
if(Input.GetKey("a")){
transform.Rotate(-Vector3.up*2);
}
if(Input.GetKey("d")){
transform.Rotate(Vector3.up*2);
}

if(_grounded)
{
//本地空间水平移动方向向量
_moveDirection = Vector3( 0 , -1 , Input.GetAxis("Vertical"));

//本地空间移动方向转为世界空间的移动方向向量
_moveDirection = transform.TransformDirection(_moveDirection);
_moveDirection *= _speed;

//重力速度还原
_gravity = _originalgravity;
}

//跳跃
if (Input.GetButton("Jump") )
{
_playerstate = PlayerState.STATE_JUMP;

//获得初速度
_moveDirection.y = _jumpspeed;

_animation.Play("jump");
}

//如果当前处于跳跃中,就算一下Y向量
if(_playerstate == PlayerState.STATE_JUMP)
{
_gravity += _addgravity;
_moveDirection.y -= _gravity * Time.deltaTime;
}

//移动,并获得碰撞标示
var _flags : CollisionFlags =_controller.Move(_moveDirection * Time.deltaTime);
//是否已经着地
_grounded = (_flags & CollisionFlags.CollidedBelow) != 0;
print(_grounded);
//=======================================================================
//攻击
if(Input.GetKeyUp("f") && _grounded && _playerstate == PlayerState.STATE_IDLE)
{
_playerstate = PlayerState.STATE_ATTACK;
_animation.Play("attack");
}

//休闲
if(_moveDirection.x == 0 && _moveDirection.z == 0 && _grounded && _playerstate != PlayerState.STATE_ATTACK)
if(_moveDirection != Vector3(0,0,0))
{
if(_playerstate != PlayerState.STATE_ATTACK)
{
_playerstate = PlayerState.STATE_IDLE;
_animation.Play("idle");
}
}

//跑动
if((_moveDirection.x != 0 || _moveDirection.z != 0) && _grounded )
{
_playerstate = PlayerState.STATE_RUN;
_animation.Play("run");
}
}
//供外部UI调用的接口,调用攻击动作
function PlayAnimation_Attack()
{
if(_grounded && (_playerstate == PlayerState.STATE_IDLE||_playerstate ==PlayerState.STATE_ATTACK))
{
_playerstate = PlayerState.STATE_ATTACK;
_animation.Play("attack");
}
}
0
点赞
0
打赏
0
添加到收藏夹

0

点击复制链接

使用微信扫码分享
一次扣10个券
全部评论6
您需要登录后才可以回帖 登录

正需要这个 看看~~~
9年前
回复

使用道具 举报

{:soso_e160:}
11年前
回复

使用道具 举报

写得不错,哈哈。可惜我不会
11年前
回复

使用道具 举报

写的还不错
11年前
回复

使用道具 举报

{:soso_e163:}{:soso_e179:}
11年前
回复

使用道具 举报

我们是不是可以,建 一个权限,比如,攻击的权限为3,行走的权限为2,站立为0,IF(正在直行的权限>新权限){直行;}ELSE不直行;我也在想这个问题,现在只想到这么多!~不过你的模型的旋有没有了新的方法呢?很期待!~
11年前
回复

使用道具 举报

您当前使用的浏览器IE内核版本过低会导致网站显示错误

请使用高速内核浏览器或其他浏览器