Roman 6c935a7d3f 任务:替换现有美术素材和动画、完善游戏的流程化
*:合并了SAIPOVersion
场景【第二关】
1.放置巡逻类敌人
*制作AC【巡逻敌人】
2.完善巡逻类敌人,具有以下特性:
(1.普通巡逻时,执行走路动画
(2.监测到玩家时,执行开枪动画
(3.给动画添加事件,开枪瞬间播放玩家死亡动画
(4.当听到石头声音,执行听见动画
(5.结束后让敌人冲向石头落地处
(6.到达石头落地处后,执行检查动画
(7.检查动画结束后,返回步行状态继续巡逻
3.布置了投掷物堆
4.布置了挡板,具有以下特性:
(1.当玩家位于挡板后,标记自身被遮挡,不会被敌人发现
(2.当玩家离开挡板后,标记自身未被遮挡,会被敌人发现
(3.修改敌人逻辑,当发现挡板后的玩家,无事发生,而当发现无遮挡的玩家,执行开枪和玩家死亡动画
5.解决了玩家转身后无法投掷的问题
6.放置了两个敌人
7.放置了两个挡板
8.布置营地
9.给桌子加上修理电报机系统
10.替换修理电报机界面UI美术素材
11.提高了修理台的转速
2021-09-03 16:03:44 +08:00

206 lines
7.1 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
public class Patrolman : MonoBehaviour
{
//控制巡逻敌人
[Tooltip("拖入巡逻点1")]
public Transform point1;
[Tooltip("拖入巡逻点2他将于此两点间往返")]
public Transform point2;
[Tooltip("普通移动时的速度")]
public float walkSpeed;
[Tooltip("听见响动,冲锋时的速度")]
public float rushSpeed;
[SerializeField][ReadOnly]
private float speed;//记录此刻瞬间的速度,不包含方向
private float velocity;//速度,正值代表向右,用来判断面部朝向
[SerializeField]
private Transform target;//当前目标位置
private bool isInterrupt = false;//记录目前是否被石头落地的声音所吸引
private float PVelocity = -1f;//记录上一帧的速度,默认上一帧往右走
private Transform auditoryRange;//听觉范围子物体
[SerializeField][ReadOnly]
private List<Missile> missiles;//投掷物列表,巡逻者会自动往搜索听觉范围内的投掷物
private Animator animator;
// Start is called before the first frame update
void Start()
{
target = point1;//初始化起始目标为巡逻点1
speed = walkSpeed;//初始化瞬间速度为走路速度
auditoryRange = transform.Find("听觉范围");//找到子物体听觉范围
auditoryRange.gameObject.AddComponent<AuditoryRange>();//给子物体听觉范围填上碰撞监测代码
missiles = new List<Missile>();//初始化投掷物列表
animator = GetComponent<Animator>();
animator.SetBool("IsWalk",true);
}
// Update is called once per frame
void Update()
{
Move();//每帧朝目标移动
CheckMissiles();//检查是否有投掷物落地
}
private void CheckMissiles()
{
foreach(Missile missile in missiles)
{
//Debug.Log(missile.AMINoisy());
if(missile.AMINoisy() && !missile.AmIBeenChecked())//如果投掷物在发声、且没有被检查过
{
Debug.Log("听见了");
//将目标位置设定为落点
target = missile.transform;
//更改速度为跑步速度
speed = rushSpeed;
//标记该投掷物已被检查
missile.YouAreChecked();
isInterrupt = true;
PVelocity = 0;
//执行听见动画
animator.SetBool("IsListen",true);
StartCoroutine("StopListen");//取消听见动画条件
}
}
}
private IEnumerator StopListen()
{
yield return new WaitForSeconds(0.1f);
animator.SetBool("IsListen",false);
animator.SetBool("IsRush",true);//开启跑步条件
animator.SetBool("IsWalk",true);//关闭走路条件
}
//朝目标移动函数
private void Move()
{
//构造速度向量
velocity = (target.position - transform.position).x;
velocity = Mathf.Abs(velocity)/velocity;//把速度标准化为1或者-1只保留方向
velocity *= speed;//给速度赋以大小
//判断是否到达巡逻点或者落点
//Debug.Log(velocity*PVelocity);
if(velocity*PVelocity < 0)//速度相乘得负数,说明方向发生改变
{
//如果计算速度发生改变,且不是因为被石头打断,说明经过了巡逻点,此时更换目标点为另一个
if(target.Equals(point1) && !isInterrupt) target = point2;
else if(target.Equals(point2) && !isInterrupt) target = point1;//不是被投掷物吸引的时候,才这样
//如果目标是投掷物的落点,恢复速度和目标点
if(target.gameObject.tag == "投掷物")
{
speed = walkSpeed;
//target = point2;
if(velocity > 0) target = point2;
else target = point1;
Debug.Log("投掷物触发转向");
isInterrupt = false;
//动画
animator.SetBool("IsCheck",true);
animator.SetBool("IsWalk",true);
animator.SetBool("IsRush",false);
StartCoroutine("StopCheckAnimation");
}
}
//控制面部朝向
if(velocity > 0) transform.rotation = Quaternion.Euler(0,0,0);
else transform.rotation = Quaternion.Euler(0,180f,0);
// //移动(改用动画移动)
// transform.position = new Vector3(
// //x
// transform.position.x +//自身此刻位置 加上
// velocity * //构造好的速度乘以
// Time.deltaTime,//使其与时间无关
// //y和z不变
// transform.position.y,
// transform.position.z
// );
//更新PVelocity
PVelocity = velocity;
}
private IEnumerator StopCheckAnimation()
{
yield return new WaitForSeconds(0.1f);
animator.SetBool("IsCheck",false);
}
//开枪动画中调用,告诉玩家你被射死了
public void OnShoot()
{
FindObjectOfType<M_Player>().YouAreShooting();
}
void OnTriggerStay2D(Collider2D other)
{
if(other.gameObject.tag == "Player")
{
if(!other.GetComponent<M_Player>().AreYouCovered())
{
animator.SetBool("IsFire",true);
}
}
}
//在听觉范围中调用,加入一个监听中的投掷物
public void AddAMissile(Missile missile){missiles.Add(missile);}
//在听觉范围中调用,移除一个监听中的投掷物
public void RemoveAMissile(Missile missile){missiles.Remove(missile);}
private class AuditoryRange : MonoBehaviour
{
void OnTriggerEnter2D(Collider2D other)
{
if(other.tag == "投掷物")
{
//当有投掷物进入听觉范围,把他加入监控内的投掷物列表
GetComponentInParent<Patrolman>().AddAMissile(other.GetComponent<Missile>());
}
}
void OnTriggerExit2D(Collider2D other)
{
if(other.tag == "投掷物")
{
//当有投掷物离开听觉范围,把他移出监控内的投掷物列表
GetComponentInParent<Patrolman>().RemoveAMissile(other.GetComponent<Missile>());
}
}
}
//制造一个只读的变量,不要动这些
public class ReadOnlyAttribute : PropertyAttribute{}
[CustomPropertyDrawer(typeof(ReadOnlyAttribute))]
public class ReadOnlyDrawer : PropertyDrawer
{
public override float GetPropertyHeight(SerializedProperty property, GUIContent label)
{
return EditorGUI.GetPropertyHeight(property, label, true);
}
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
{
GUI.enabled = false;
EditorGUI.PropertyField(position, property, label, true);
GUI.enabled = true;
}
}
//
}