Unity 类胡闹厨房游戏 KitchenChaos 阶段1(至视频12)整理记录

原教程地址:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Player : MonoBehaviour
{
    [SerializeField] private float moveSpeed = 7f;
    [SerializeField] private GameInput gameInput;
    //角色变换朝向的速度
    [SerializeField] private float rotateSpeed = 100f;
    private float playerHeight = 2f;
    private float playerRadius = .7f;

    //判断当前是否在行走,传值到动画
    private bool isWalking;
    // Update is called once per frame
    private void Update()
    {
        Vector2 inputVector = gameInput.GetMovementVectorNormalized();
        Vector3 moveDir = new Vector3(inputVector.x, 0f, inputVector.y);

        float moveDistance = moveSpeed * Time.deltaTime;

        bool canMove = !Physics.CapsuleCast(transform.position, transform.position + Vector3.up * playerHeight, playerRadius, moveDir,moveDistance);
        //如果同时按住右移动和上移动时遇到障碍物时角色会无法移动,这时其实应该允许角色朝无障碍物的右/上单方向移动
        if (!canMove)
        {
            Vector3 moveX = new Vector3(moveDir.x, 0f, 0f).normalized;
            Vector3 moveZ = new Vector3(0f, 0f, moveDir.z).normalized;

            canMove = (moveDir.x < -0.5f || moveDir.x > 0.5f) && !Physics.CapsuleCast(transform.position, transform.position + Vector3.up * playerHeight, playerRadius, moveX, moveDistance);
            if (canMove)
            {
                moveDir = moveX;
            }
            else
            {
                canMove = (moveDir.z < -0.5f || moveDir.z > 0.5f) && !Physics.CapsuleCast(transform.position, transform.position + Vector3.up * playerHeight, playerRadius, moveZ, moveDistance);
                if (canMove)
                {
                    moveDir = moveZ;
                }
            }
        }
        if (canMove)
        {
            transform.position += moveDir * Time.deltaTime * moveSpeed;
        }
        
        isWalking = (moveDir != Vector3.zero);
        
        if (moveDir != Vector3.zero)
        {
            transform.forward = Vector3.Slerp(transform.forward, moveDir, Time.deltaTime * rotateSpeed);
        }
        
    }

    public bool IsWalking()
    {
        return isWalking;
    }
}
Player.cs

 

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class GameInput : MonoBehaviour
{
//新inputSystem
    private PlayerInputActions inputActions;
    private void Awake()
    {
        inputActions = new PlayerInputActions();
        inputActions.Player.Enable();
    }
    public Vector2 GetMovementVectorNormalized()
    {
//通过readValue来获取输入的方向
        Vector2 inputVector = inputActions.Player.Move.ReadValue<Vector2>();
        inputVector = inputVector.normalized;//归一化
        Debug.Log(inputVector);
        return inputVector;
    }

}
GameInput.cs

 

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class PlayerAnimator : MonoBehaviour
{
    private const string IS_WALKING = "IsWalking";
    [SerializeField] private Player player;
    private Animator animator;
    private void Awake()
    {
        animator = GetComponent<Animator>();
    }
    private void Update()
    {
        animator.SetBool(IS_WALKING, player.IsWalking());
    }
}
PlayerAnimator.cs

 

重点记要:

1.添加后处理的操作为:在Global Volume上添加override,之后可添加Tonemapping、Color Adjustments、Bloom、Vignette等

2.角色逻辑、角色动画逻辑、角色输入分离,动画中需要用到的参数可通过在角色动画的script里借助如下来实现分离。

[SerializeField] private Player player;
同时传参要用函数返回对应的bool值

3.角色转向使用的是forward来控制,注意这里使用的是slerp进行差值,角色forward朝向的Vector3为全零会报错,注意避免

transform.forward = Vector3.Slerp(transform.forward, moveDir, Time.deltaTime * rotateSpeed);
forward

 4.角色的方向要时刻注意归一化,无论是在输入的时候设置还是代码中normalize

 5.在射线检测中Physics.Raycast(transform.position, lastInteractDir, out RaycastHit raycastHit, interactDistance, counterLayer) 借助out RaycastHit raycastHit来获取碰撞到的物体信息

通过raycastHit.transform.TryGetComponent(out BaseCounter clearCounter)检测碰撞物体挂的脚本情况,相比于GetComponent<BaseCounter>还需要再判是否为空这样更加简洁

posted @ 2024-02-16 18:20  LOFU  阅读(104)  评论(0编辑  收藏  举报