Unity 类胡闹厨房游戏 KitchenChaos 阶段1(至视频12)整理记录
原教程地址:https://youtu.be/AmGSEH7QcDg
部分代码:
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; } }
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; } }
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()); } }
重点记要:
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);
4.角色的方向要时刻注意归一化,无论是在输入的时候设置还是代码中normalize
5.在射线检测中Physics.Raycast(transform.position, lastInteractDir, out RaycastHit raycastHit, interactDistance, counterLayer) 借助out RaycastHit raycastHit来获取碰撞到的物体信息
通过raycastHit.transform.TryGetComponent(out BaseCounter clearCounter)检测碰撞物体挂的脚本情况,相比于GetComponent<BaseCounter>还需要再判是否为空这样更加简洁