[Unity实践笔记] 俯视视角人物360°移动脚本

实现效果

俯视视角下,wasd控制人物移动,人物可进行360°流畅转身。
在这里插入图片描述

知识点

角度计算:绕y轴软转到direction方向需要转多少度

float angle = Vector3.Angle(new Vector3(0, 1, 0), direction);

局部坐标系中旋转(0, 0 , angle)

transform.localEulerAngles = new Vector3(0, 0, angle);

 
不使用transform.Rotate(vec3)的原因
Rotate(vec3)为旋转vec3角度(相对角度),只要按键按下左右键就会执行,会达到令人凌乱的效果。
localEulerAngles(vec3)为旋转到vec3角度(绝对角度),如果已经到达该角度,再怎么按左右键都不会过度旋转。
 

代码

  1. 挂载在玩家Object
// Attached on playerObj
public class PlayerController : MonoBehaviour
{
    
    
    public float speed = 1.0f;
    public Animator anim;

    private void Start()
    {
    
    
        anim = GetComponentInChildren<Animator>();
    }

    void FixedUpdate()
    {
    
    
        float xPosition = Input.GetAxis("Horizontal") * speed;
        float yPosition = Input.GetAxis("Vertical") * speed;

        if (Input.GetKey("a")||Input.GetKey("d")||Input.GetKey("w")||Input.GetKey("s"))
        {
    
    
            transform.Translate(xPosition, yPosition, 0);
            //animator.SetBool("isWalking", true);
        }

        anim.SetFloat("speed", Mathf.Abs(xPosition)+Mathf.Abs(yPosition));

        //else animator.SetBool("isWalking", false);
    }

此脚本只负责移动玩家Object,不管玩家如何旋转。

注意:若带有RigidBody组件,必须使用FixedUpdate(),否则会解锁奇奇怪怪的移动方式。
 

  1. 挂载在玩家Object子物体,sprite上(带有玩家sprite和animator)
// Attached on player-spriteObj
public class SpriteSpinner : MonoBehaviour
{
    
    
    SpriteRenderer spriteRenderer;
    Vector3 direction;
    bool moveV;
    bool moveH;

    // Start is called before the first frame update
    void Start()
    {
    
    
        spriteRenderer = GetComponent<SpriteRenderer>();
    }


    // Update is called once per frame
    void Update()
    {
    
    
        direction.x = Input.GetAxis("Horizontal");
        direction.y = Input.GetAxis("Vertical");

        if(direction.x == 0 && direction.y != 0){
    
    
            moveV = true;
            moveH = false;
        }
        else if(direction.y == 0 && direction.x != 0){
    
    
            moveH = true;
            moveV = false;
        }
        else{
    
    
            moveH = false;
            moveV = false;
        }

        if(moveV){
    
    
            int rotateY = direction.y > 0 ? 0 : 180;

            transform.localEulerAngles = new Vector3(0, 0, rotateY);
        }
        else if(moveH){
    
    
            int rotateX = direction.x > 0 ? -90 : 90;

            transform.localEulerAngles = new Vector3(0, 0, rotateX);
        }
        else{
    
    
                int signX = direction.x < 0 ? 1 : -1;
                float angle = signX * Vector3.Angle(new Vector3(0, 1, 0), direction);
        

                if(angle != 0) transform.localEulerAngles = new Vector3(0, 0, angle);
        }
    }
}

此脚本只负责旋转玩家带有sprite组件的子物体(即子物体的旋转不会影响玩家整体的移动方向)
 

Bug & 待修改

停止控制后会自动旋转一定角度

猜你喜欢

转载自blog.csdn.net/weixin_44045614/article/details/108434919