15.游戏场景-玩家逻辑
15.1 知识点
创建PlayerObject脚本,继承Monobehaviour,挂载到各个角色上,给各个角色添加角色控制器组件,防止穿模。
初始化玩家属性:定义Animator组件。在Start()方法中获取Animator组件。定义了玩家的攻击、拥有的钱、旋转的速度、开火点位置。提供初始化玩家基础属性的方法,初始化攻击力和拥有的钱,调用之后写的更新钱的方法更新钱,之后再外部调用。
public class PlayerObject : MonoBehaviour
{
//Animator组件
private Animator animator;
void Start()
{
// 获取Animator组件
animator = this.GetComponent<Animator>();
}
//玩家攻击力
private int atk;
//玩家拥有的钱
public int money;
//旋转的速度
private float roundSpeed = 50;
//持枪对象才有的开火点
public Transform gunPoint;
/// <summary>
/// 初始化玩家基础属性
/// </summary>
/// <param name="atk"></param>
/// <param name="money"></param>
public void InitPlayerInfo(int atk, int money)
{
this.atk = atk;
this.money = money;
//更新界面上钱的数量
UpdateMoney();
}
}
移动和动作变化:在Update中,使用Input.GetAxis获取玩家输入的垂直和水平方向的值,并通过设置水平和竖直动画参数控制移动动作的变换。通过transform.Rotate旋转API,使用Input.GetAxis获取鼠标在水平方向上的移动值乘以定义的旋转速度和时间间隔来控制角色的旋转。通过按下左Shift键切换到第二层动画,松开时切回第一层动画。按下R键时触发Roll动画,鼠标左键按下时触发Fire动画。
void Update()
{
// 通过输入控制移动动作的变换,根据输入的垂直方向上的值设置VSpeed参数,
// 根据输入的水平方向上的值设置HSpeed参数,实现动作的变化和速度的变化
animator.SetFloat("VSpeed", Input.GetAxis("Vertical"));
animator.SetFloat("HSpeed", Input.GetAxis("Horizontal"));
// 通过鼠标的移动控制角色的旋转,根据鼠标在水平方向上的移动值乘以旋转速度和时间间隔,
// 使用Transform组件的Rotate方法实现角色的旋转
this.transform.Rotate(Vector3.up, Input.GetAxis("Mouse X") * roundSpeed * Time.deltaTime);
// 按下左Shift键时,设置第二层动画权重为1,表示切换到第二层动画
if (Input.GetKeyDown(KeyCode.LeftShift))
{
animator.SetLayerWeight(1, 1);
}
// 松开左Shift键时,设置第二层动画权重为0,表示切回到第一层动画
else if (Input.GetKeyUp(KeyCode.LeftShift))
{
animator.SetLayerWeight(1, 0);
}
// 按下R键时,设置Roll触发器,播放Roll动画
if (Input.GetKeyDown(KeyCode.R))
animator.SetTrigger("Roll");
// 鼠标左键按下时,设置Fire触发器,播放Fire动画
if (Input.GetMouseButtonDown(0))
animator.SetTrigger("Fire");
}
攻击动作的处理:在各个角色的开火动画中添加对应事件,函数名要对应,记得应用。注意由于一些角色的动画是覆盖的,只能去Animator文件中查看对应动画,在Animator窗口查看的话还是会跳转到覆盖源动画。添加怪物Monster层,之后做怪物时把怪物设置成Monster层。在用刀伤害事件KnifeEvent()方法中,使用OverlapSphere方法检测前方1米范围内带有Monster层的碰撞体,然后遍历碰撞到的对象,执行受伤的逻辑待有怪物后补充。要为每一个拿枪的角色创建一个开火点,注意朝向。在用枪伤害事件ShootEvent()方法中,使用RaycastAll方法从开火点位置向前发射射线,检测碰撞到的带有Monster层的物体,然后遍历碰撞到的对象,执行受伤的逻辑待有怪物后补充。
/// <summary>
/// 专门用于处理刀武器攻击动作的伤害检测事件
/// </summary>
public void KnifeEvent()
{
// 进行伤害检测,使用OverlapSphere方法检测前方1米范围内带有Monster层的碰撞体
Collider[] colliders = Physics.OverlapSphere(this.transform.position + this.transform.forward + this.transform.up, 1, 1 << LayerMask.NameToLayer("Monster"));
// 循环遍历所有碰撞到的对象,获取怪物脚本并让其受伤
for (int i = 0; i < colliders.Length; i++)
{
// 得到碰撞到的对象上的怪物脚本,执行受伤逻辑
}
}
/// <summary>
/// 专门用于处理枪武器开火动作的伤害检测事件
/// </summary>
public void ShootEvent()
{
// 进行射线检测,从开火点位置向前发射射线,检测碰撞到的带有Monster层的物体
RaycastHit[] hits = Physics.RaycastAll(new Ray(gunPoint.position, gunPoint.forward), 1000, 1 << LayerMask.NameToLayer("Monster"));
// 循环遍历所有射线碰撞到的对象,获取怪物脚本并让其受伤
for (int i = 0; i < hits.Length; i++)
{
// 得到碰撞到的对象上的怪物脚本,执行受伤逻辑
}
}
钱的变化逻辑:定义更新更新界面上钱的数量方法UpdateMoney(),通过UIManager的实例获取GamePanel,并调用GamePanel更新钱方法其上显示的钱的数量。定义提供给外部加钱的方法AddMoney(int money),外部传入钱的数量,增加钱的数量,然后调用UpdateMoney()方法更新界面上的钱的数量。
/// <summary>
/// 更新界面上钱的数量
/// </summary>
public void UpdateMoney()
{
// 通过UIManager的实例获取GamePanel,并更新其上显示的钱的数量
UIManager.Instance.GetPanel<GamePanel>().UpdateMoney(money);
}
/// <summary>
/// 提供给外部加钱的方法
/// </summary>
/// <param name="money">要增加的钱的数量</param>
public void AddMoney(int money)
{
// 增加钱的数量
this.money += money;
// 更新界面上钱的数量
UpdateMoney();
}
15.2 知识点代码
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerObject : MonoBehaviour
{
//1.玩家属性的初始化
//Animator组件
private Animator animator;
void Start()
{
// 获取Animator组件
animator = this.GetComponent<Animator>();
}
//玩家攻击力
private int atk;
//玩家拥有的钱
public int money;
//旋转的速度
private float roundSpeed = 50;
//持枪对象才有的开火点
public Transform gunPoint;
/// <summary>
/// 初始化玩家基础属性
/// </summary>
/// <param name="atk"></param>
/// <param name="money"></param>
public void InitPlayerInfo(int atk, int money)
{
this.atk = atk;
this.money = money;
//更新界面上钱的数量
UpdateMoney();
}
//2.移动变化 动作变化
void Update()
{
// 通过输入控制移动动作的变换,根据输入的垂直方向上的值设置VSpeed参数,
// 根据输入的水平方向上的值设置HSpeed参数,实现动作的变化和速度的变化
animator.SetFloat("VSpeed", Input.GetAxis("Vertical"));
animator.SetFloat("HSpeed", Input.GetAxis("Horizontal"));
// 通过鼠标的移动控制角色的旋转,根据鼠标在水平方向上的移动值乘以旋转速度和时间间隔,
// 使用Transform组件的Rotate方法实现角色的旋转
this.transform.Rotate(Vector3.up, Input.GetAxis("Mouse X") * roundSpeed * Time.deltaTime);
// 按下左Shift键时,设置第二层动画权重为1,表示切换到第二层动画
if (Input.GetKeyDown(KeyCode.LeftShift))
{
animator.SetLayerWeight(1, 1);
}
// 松开左Shift键时,设置第二层动画权重为0,表示切回到第一层动画
else if (Input.GetKeyUp(KeyCode.LeftShift))
{
animator.SetLayerWeight(1, 0);
}
// 按下R键时,设置Roll触发器,播放Roll动画
if (Input.GetKeyDown(KeyCode.R))
animator.SetTrigger("Roll");
// 鼠标左键按下时,设置Fire触发器,播放Fire动画
if (Input.GetMouseButtonDown(0))
animator.SetTrigger("Fire");
}
//3.攻击动作的不同处理
/// <summary>
/// 专门用于处理刀武器攻击动作的伤害检测事件
/// </summary>
public void KnifeEvent()
{
// 进行伤害检测,使用OverlapSphere方法检测前方1米范围内带有Monster层的碰撞体
Collider[] colliders = Physics.OverlapSphere(this.transform.position + this.transform.forward + this.transform.up, 1, 1 << LayerMask.NameToLayer("Monster"));
// 循环遍历所有碰撞到的对象,获取怪物脚本并让其受伤
for (int i = 0; i < colliders.Length; i++)
{
// 得到碰撞到的对象上的怪物脚本,执行受伤逻辑
}
}
/// <summary>
/// 专门用于处理枪武器开火动作的伤害检测事件
/// </summary>
public void ShootEvent()
{
// 进行射线检测,从开火点位置向前发射射线,检测碰撞到的带有Monster层的物体
RaycastHit[] hits = Physics.RaycastAll(new Ray(gunPoint.position, gunPoint.forward), 1000, 1 << LayerMask.NameToLayer("Monster"));
// 循环遍历所有射线碰撞到的对象,获取怪物脚本并让其受伤
for (int i = 0; i < hits.Length; i++)
{
// 得到碰撞到的对象上的怪物脚本,执行受伤逻辑
}
}
//4.钱变化的逻辑
/// <summary>
/// 更新界面上钱的数量
/// </summary>
public void UpdateMoney()
{
// 通过UIManager的实例获取GamePanel,并更新其上显示的钱的数量
UIManager.Instance.GetPanel<GamePanel>().UpdateMoney(money);
}
/// <summary>
/// 提供给外部加钱的方法
/// </summary>
/// <param name="money">要增加的钱的数量</param>
public void AddMoney(int money)
{
// 增加钱的数量
this.money += money;
// 更新界面上钱的数量
UpdateMoney();
}
}
转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 785293209@qq.com