Unity第三人称

一、摄像机绕转脚本
1、定义游戏对象
[SerializeField] private Transform target;
使用Transform是因为所有的游戏对象的层级视图里面都有Transform属性。定义Transform和定义GameObject是等同的。大多数情况下都可以把游戏对象定义为Transform,Transform这个类型会有很多方便的方法。
2、起始角度和偏移值的初始化
//起始的y的角度
_rotY = transform.eulerAngles.y;
//偏移值=player的位置减掉摄像机的位置
_offset = target.position - transform.position;
使用四元数,偏移值使得摄像机始终指向某一个位置,做差值比较方便
3、LateUpdate方法中控制摄像机位置的移动
也是逐帧执行,区别于Update, LateUpdate是所有的Update做完之后再执行

float horInput = Input.GetAxis("Horizontal");
        if(horInput!=0)
        {
            //键盘旋转摄像机
            _rotY += horInput * rotSpeed;
        }
        else
        {
            //使用鼠标快速旋转摄像机
            _rotY += Input.GetAxis("Mouse X") * rotSpeed * 3;
        }
        Quaternion rotation = Quaternion.Euler(0, _rotY, 0);
        transform.position = target.position - (rotation * _offset);
        transform.LookAt(target);

基于目标的位置和旋转值来定位摄像机,Quaternion来存储和表示对象的旋转角度
①Quaternion rotation = Quaternion.Euler(0, _rotY, 0);
四元数表示对象的旋转角度。摄像机的旋转与移动,X方向移动鼠标或者按键盘会产生X方向的旋转,旋转角度为_rotY,这个角度通过鼠标的输入或者键盘的输入来确定
②transform.position = target.position - (rotation * _offset);
摄像机的位置为玩家的位置再减掉偏移值成旋转的角度
③transform.LookAt(target);
使摄像机朝向玩家
二、player绕摄像机移动
先转方向后移动
1、关联摄像机
[SerializeField] private Transform target;
2、针对着摄像机进行左右的运动

Quaternion direction = Quaternion.LookRotation(movement);
transform.rotation = Quaternion.Lerp(transform.rotation, direction, rotSpeed * Time.deltaTime);

三、利用垂直速度和加速度实现起跳和下落
1、定义

public float jumpSpeed = 15.0f;//跳跃时向上的速度
public float gravity = -9.8f;//重力加速度
public float terminalVelocity = -10.0f;//最大的向下速度
public float minFall = -1.5f;//默认状态下给的向下的速度
private float _vertSpeed;//当前速度

2、在Update方法中产生相应的控制

if(_charController.isGrounded)//在地面
        {
            if(Input.GetButtonDown("Jump"))//按下空格
            {
                _vertSpeed = jumpSpeed;//给一个向上的速度
            }
            else
            {
                _vertSpeed = minFall;//给一个向下的速度压着
            }
        }
        else//不在地面
        {
            _vertSpeed += gravity * 5 * Time.deltaTime;//速度快速减小
            if(_vertSpeed<terminalVelocity)//下落速度最小为terminalVelocity
            {
                _vertSpeed = terminalVelocity;
            }
        }
        movement.y = _vertSpeed;

分为player是否在地面上的判断。在地面上的话就判断时候按下跳跃的按键(默认空格),如果按下就给_vertSpeed速度向上,如果没有按下就给_vertSpeed速度向下,使得player在地面上。不在地面上的话就让_vertSpeed加上重力加速度使得_vertSpeed减小,模拟重力加速度的作用,等到_vertSpeed一直减小到terminalVelocity这个最小的下落速度的时候保持这个速度不变直到到达地面。最后给movement.y = _vertSpeed实现player的移动
3、在边缘会产产生悬空的行为
解决方法:从player的脚底打出一条射线,会返回player和地面之间距离。如果这个值小于某个值则是在地面上,如果大于这个值则处于悬空状态。
在这里插入图片描述

1)定义变量
private ControllerColliderHit _contract;
2)

if(_vertSpeed<0&&Physics.Raycast(transform.position,Vector3.down,out hit))
        {
            float check = (_charController.height + _charController.radius) / 1.9f;
            hitGround = hit.distance <= check;
        }

用于确定hitGround的值,如果说hit.distance <= check就说明还在地面上,所以hitGround=true;否则说明不在地面上,hitGround=false
2)

if(hitGround)
        {
            if(Input.GetButtonDown("Jump"))
            {
                _vertSpeed = jumpSpeed;
            }
            else
            {
                _vertSpeed = minFall;
            }
        }
        else//不在地面
        {
            _vertSpeed += gravity * 5 * Time.deltaTime;//速度快速减小
            if(_vertSpeed<terminalVelocity)//下落速度最大为terminalVelocity
            {
                _vertSpeed = terminalVelocity;
            }
            if (_charController.isGrounded)
            {
                if (Vector3.Dot(movement, _contract.normal) < 0)//朝外
                {
                    movement = _contract.normal * moveSpeed;
                }
                else
                {
                    movement += _contract.normal * moveSpeed;
                }
            }
        }

如果在地面上,在判断是否按下“Jump”按键。如果按下了还是给player一个向上的速度,如果没有按下就给一个向下的速度压住;如果不在地面上,给当前速度_vertSpeed加上重力加速度使得速度不断减小,同样当速度等于某一个值terminalVelocity的时候使得速度不再改变。还要判断_charController.isGrounded是否在地面上,如果在,继续判断Vector3.Dot(movement, _contract.normal) < 0是否成立,成立即player是朝外的,就让movement = _contract.normal * moveSpeed;;否则,说明是朝内的,就让movement += _contract.normal moveSpeed;。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值