[脚本编程] 人物控制脚本的实现

http://bbs.9ria.com/thread-119529-1-15.html

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


对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");
}
}


posted @ 2012-08-03 17:29  渡蓝  阅读(631)  评论(0)    收藏  举报