Animator 与Animator Controller
Animator(动画)是游戏角色的基本属性,比如一个任务在屏幕上移动,是靠播放动画实现的。Animator Controller相当于一个状态机,在不同的动画之间进行切换。比如人物移动是一个动画,如果停止按下移动键,那么会切换到静止的状态;如果任务死亡,会播放死亡的动画。这一切靠的是Animator Controller进行的自动切换。
在一个GameObject中添加一个Animator的Component组件,然后再创建一个Animator Controller的组件,拖拽到GameObject上。在Animator Controller内部进行一些状态转换的处理即可。
本例子中的处理方式:
Animator anim;
void Animating(float h,float v) {
bool walking = (h != 0 || v != 0);
if (walking) {
anim.SetBool("IsWalking", walking);
}
}
Vector3的正则化
如果同时按下W+D,那么会叠加一个新的移动向量,但是这个向量的长度是2,我们想要让它是 ,所以要进行正则化:
void Move(float h,float v) {
movement.Set(h, 0f, v);
movement = movement.normalized * speed * Time.deltaTime;
playerRigidBody.MovePosition(transform.position + movement);
}
人物跟随鼠标旋转的方式
这是3D游戏中,很常用的一种方式。人物前进的方向,始终是鼠标当前在屏幕上的位置。需要借助几个主要的类进行实现。
Ray
代表了场景中的射线(光线),是一个无限长的线段,有一个起点,没有终点。
构造方式:
public Ray(Vector3 origin, Vector3 direction);
方向属性:
public Vector3 direction;
起点位置:
public Vector3 origin;
Tag和Layer
tag是每个游戏中物体的一个名称的标识,字符串类型的。一般用于物体的分类,碰撞检测的过滤等,也是为了方便查找物体,tag的个数不限。
Layer可以理解为图层,一般用于光线投射的渲染,可以使用Camera来指出哪些Layers需要显示,让Light指出那些Layers需要被照明,让物理射线指出哪些Layers可以被侦测到。
LayerMask
用于设定一个Layer属性值的变量。
Physics.Raycast和RaycastHit
一个静态方法,用于光线投射。
public static bool Raycast(Vector3 origin, Vector3 direction,
float maxDistance = Mathf.Infinity,
int layerMask = DefaultRaycastLayers,
QueryTriggerInteraction queryTriggerInteraction = QueryTriggerInteraction.UseGlobal);
参数说明:
origin
:射线的起点direction
:射线的方向maxDistance
:射线检测碰撞的最大距离layerMask
:当投射光线时,有选择性的忽略碰撞。指定该值后,layer为这个编号的会被射线忽略queryTriggerInteraction
:指出应该触发Trigger的query
如果与一个Collider相交,返回Tru;否则返回False。
RaycastHit
是一个用于获取一个射线投射的结构体
两者结合的方式:
using UnityEngine;
public class ExampleClass : MonoBehaviour
{
// C# example.
void Update()
{
// Bit shift the index of the layer (8) to get a bit mask
int layerMask = 1 << 8;
// This would cast rays only against colliders in layer 8.
// But instead we want to collide against everything except layer 8. The ~ operator does this, it inverts a bitmask.
layerMask = ~layerMask;
RaycastHit hit;
// Does the ray intersect any objects excluding the player layer
if (Physics.Raycast(transform.position, transform.TransformDirection(Vector3.forward), out hit, Mathf.Infinity, layerMask))
{
Debug.DrawRay(transform.position, transform.TransformDirection(Vector3.forward) * hit.distance, Color.yellow);
Debug.Log("Did Hit");
}
else
{
Debug.DrawRay(transform.position, transform.TransformDirection(Vector3.forward) * 1000, Color.white);
Debug.Log("Did not Hit");
}
}
}
Camera.main.ScreenPointToRay
这是一个屏幕光线投射的点。
public Ray ScreenPointToRay(Vector3 pos);
pos
是选择屏幕上的点。返回一个Ray。
最终的一般性解决方案
int floorMask; // 忽略最初设定的地板
float camRayLength = 100.0f; // 设定光线长度
void Turning() {
// 获取投射光线
Ray camRay = Camera.main.ScreenPointToRay(Input.mousePosition);
// 获取投射点
RaycastHit floorHit;
// 实际的计算,注意out的方式获取数据
if(Physics.Raycast(camRay,out floorHit, camRayLength, floorMask)) {
// 计算偏移方向,注意本例子的y不能转向
Vector3 playerToMouse = floorHit.point - transform.position;
playerToMouse.y = 0f;
// 产生转向
Quaternion newRotation = Quaternion.LookRotation(playerToMouse);
playerRigidBody.MoveRotation(newRotation);
}
}