通过一阵子的学习,我是这么认为的,因为该教程是难度两星的教程 ,也就是适合学了一阵子基础组件以后的学习者
(什么都不会的学习者要是学这套课程会困难重重,如果你什么都不会那么需要学习一星教程)
所以该课程没有那么多manger,代码也不那么面向对象,但是从怪物类之后就开始有相关的内容了,建议熟练面向对象的知识以后再来学习后面的内容
C# & Unity 面向对象补全计划 之 继承(字段与属性)_unity继承属性-CSDN博客
C# & Unity 面向对象补全计划 之 初识继承方法与多态_unity 类的继承和多态-CSDN博客
C# & Unity 面向对象补全计划 之 接口-CSDN博客
本文实现结果如下
1.怪物基类
思考
1.怪物要有速度,所以设置三种默认速度,追击速度,当前速度
2.怪物要有朝向,可以实时获取当前的朝向
3.怪物要移动,所以需要刚体组件
4.怪物要有动画,所以需要动画组件
5.怪物需要切换速度,所以要追加条件
代码
using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class Monster : MonoBehaviour
{[Header("速度")]public float normalSpeed;public float chaseSpeed;public float currentSpeed;[Header("面朝向")]private Vector3 headFor;[Header("组件")]private Rigidbody2D rb;private Animator animator;private void Awake() {rb = GetComponent<Rigidbody2D>();animator = GetComponent<Animator>();}private void Update() {//实时面朝向headFor = new Vector3(-this.transform.localScale.x,0,0);}private void FixedUpdate() {Move();}public void Move(){//移动算式rb.velocity=new Vector2( currentSpeed* headFor.x*Time.deltaTime,rb.velocity.y); }
}
2.野猪的动画
思考
1.动画应该以什么条件切换?
因为怪物不像玩家一样用按键控制加速,是监测范围内出现玩家后,触发追击,反之亦然,所以适合用bool值来切换速度响应状态,也就是切换动画
(当然麦扣老师的考量就是继承怪物类的多种怪物,不靠一种速度模式触发,这样说也合理)
2.撞墙怎么办?
撞墙和检测玩家后切换动画状态属于同一种解决方法,都是用范围检测去判断
问题1
怪物的移动方法与散步逻辑,这里还要加入检测到玩家后跑步逻辑
结合问题2的撞墙范围检测来讲,相信并不难写了
//移动方法protected virtual void Move(){//移动算式rb.velocity=new Vector2( currentSpeed* headFor.x*Time.deltaTime,rb.velocity.y);if(!(physicscheck.isLeftWall&& physicscheck.isRightWall)){isWalk = true;animator.SetBool("walk", isWalk); }else{isWalk = false;}}
问题2
撞墙检测
using System.Collections;
using System.Collections.Generic;
using Unity.VisualScripting;
using UnityEngine;public class PhysicsCheck : MonoBehaviour
{//地面检测public bool isGround;public bool isLeftWall;public bool isRightWall;//检测半径public float raduis;//检测层级private LayerMask ground;//检测偏移量[Header("偏移量")]public Vector2 positionWithOffset;public Vector2 leftOffset;public Vector2 rightOffset;private void Start() { ground = LayerMask.GetMask("Ground"); }private void Update() {Check();}private void Check(){isGround = Physics2D.OverlapCircle((Vector2)this.transform.position + positionWithOffset, raduis, ground);isLeftWall = Physics2D.OverlapCircle((Vector2)this.transform.position + leftOffset, raduis, ground);isRightWall = Physics2D.OverlapCircle((Vector2)this.transform.position + rightOffset, raduis, ground);Debug.Log("isGround: " + isGround);Debug.Log("isLeftWall: " + isLeftWall);Debug.Log("isRightWall: " + isRightWall);}private void OnDrawGizmosSelected() {Gizmos.DrawWireSphere((Vector2)this.transform.position + positionWithOffset, raduis);Gizmos.DrawWireSphere((Vector2)this.transform.position + leftOffset, raduis);Gizmos.DrawWireSphere((Vector2)this.transform.position + rightOffset, raduis);}}
撞墙等待后转身的计时器
//撞墙等待转身方法protected void WaitAndTurn(){ if(waitState){waitClock -= Time.deltaTime;if(waitClock<= 0){waitState=false;waitClock = waitTime; // 重置计时器this.transform.localScale = new Vector3(headFor.x,1,1);} }}
撞墙以后原地等待同步动画的逻辑
//实时面朝向headFor = new Vector3(-this.transform.localScale.x,0,0);if ((headFor.x > 0 && physicscheck.isRightWall) || (headFor.x < 0 && physicscheck.isLeftWall)) {waitState = true;animator.SetBool("walk", false);}//延迟转身WaitAndTurn();