SAIPO 4e37998e72 *.合并了分支
1.处理了昨天提出的建议
 1)给第一个CG加上了音效,已经上传Coding
 2)给第一关添加了微弱的雨声
 3)触发老兵牺牲时添加了管弦乐
 4)发令员和敌人被吸引的音效已经裁剪完成,在Soundeffect文件夹里,罕见语音1-7
 5)添加了发报机启动和记录纸张被撕去的声音
 6)修正了第二关的视差组件
 7)稍微优化了第二关背景火光,但还需要再研究
 8)机枪开枪音效已经替换为更有力的
 9)修正了第二关夜晚的蟋蟀声音

2.二进制文件(音乐,图片等不能直接以文本表示的文件)无法参与分支合并,导致我这里程序改过的电报音乐还是之前的,建议以后处理这类文件直接添加新文件

3.对玩家回去看老兵事件的建议
  直接弹出对话
  1)......
  2)(肩章上面写着 八路军 中华民国28年度配用)
  3)可以休息了,同志。
  4)任务很紧急,要继续前进了。
2021-09-10 22:17:49 +08:00

444 lines
17 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 UnityEngine.InputSystem;
using UnityEngine.InputSystem.Interactions;
using UnityEngine.UI;
using Cinemachine;
public class M_Player : MonoBehaviour
{
//玩家类,主要用来控制玩家
private IndexRecoder indexRecoder;//记录组件,内存方便修改的参数
private Vector2 velocity;//逻辑速度,通过计算获得,最后加在理论速度上
private Rigidbody2D m_rigidbody;//自身刚体组件
private int inputDir;//输入方向方向,-1\0\1
private int faceDir;//面部朝向,-1、1
private float runSpeedMultiple = 1f;//速度倍率,在按下和释放跑步后被修改
[Tooltip("所捕捉到的可交互对象,不要手动赋值,这个会自己捕捉")]
public Interactive catched;//所捕捉到的可交互对象
private bool throwingState = false;//记录当前是否在投掷状态
private PlayerInput playerInput;//自身输入组件,用来切换操控地图
private bool canAdjustTheAngle = false;//记录此时自己是否能调整投掷角
[SerializeField]
private float throwingAngle = 45f;//记录投掷的角度.默认是45°
private float throwingAngleDir;//记录此时投掷角度变化的速度,包括大小和方向,-1~1表示
[Tooltip("投掷物的预制体")]
public GameObject missile;//投掷物的预制体
[Tooltip("投掷物抛出点")]
public Transform throwOffset;//记录一下抛出点的位置
private Animator M_Animator;
private float strengthOfThrowing;//投掷力度,每次和投掷物堆交互,都会更新这个数值
public AudioSource machineAudio;
private bool isCovered = false;//记录自身现在是否被掩护,挡板中使用
[Tooltip("请拖入走路音效")]
public AudioClip[] walkSEs;
[Tooltip("请拖入跑步音效")]
public AudioClip[] RunSEs;
private AudioSource audioPlayer;
[Tooltip("拖入修复电报线的音效")]
public AudioClip ReapareTelephoneLineSE;
[Tooltip("拖入爬出坑的音效")]
public AudioClip upHoleSE;
[Tooltip("拖入掉入坑的音效")]
public AudioClip dropHoleSE;
[Tooltip("拖入捡东西的音效")]
public AudioClip pickSE;
[Tooltip("拖入丢东西的音效")]
public AudioClip throwSE;
void Start()
{
indexRecoder = FindObjectOfType<IndexRecoder>();//获取数值记录组件,方便策划修改暴露参数
m_rigidbody = GetComponent<Rigidbody2D>();//获取自身刚体组件
faceDir = 1;//默认面部朝右
playerInput = GetComponent<PlayerInput>(); //获取自身输入组件
M_Animator = GetComponent<Animator>();
//为了解决warming最后阶段请删除到那时应该不会再有警告
if(inputDir == 0){}
//
audioPlayer = GetComponent<AudioSource>();
}
// Update is called once per frame
void Update()
{
AdjustTheAngle();
}
//动画中调用,播放捡拾东西的音效
public void OnPickSE()
{
audioPlayer.clip = pickSE;
audioPlayer.volume = 1f;
audioPlayer.Play();
}
//动画中调用,播放丢出东西的音效
public void OnThrowSE()
{
audioPlayer.clip = throwSE;
audioPlayer.volume = 1f;
audioPlayer.Play();
}
//返回面部朝向的函数,在上下坑点调用,用来判断是否执行上下坑动画
public int ReturnFaceDir(){return faceDir;}
//播放上坑动画
public void PlayUpAnimation(){M_Animator.SetBool("IsUp",true);}
//播放下坑动画的函数,在下坑点调用
public void PlayDownAnimation(){M_Animator.SetBool("IsDown",true);}
//关闭下坑条件在动画中添加Event来执行避免下坑动画重复执行
public void StopIsDown(){M_Animator.SetBool("IsDown",false);}
//给自生刚体一个向上的速度不然无法解决动画上坑y轴被重力控制的问题
public void GiveAUpForce(){
if(gameObject.name == "他爸")
m_rigidbody.velocity = new Vector2(0,6);
else
m_rigidbody.velocity = new Vector2(0,8);//匹配不同的两个坑
}
//关闭上坑条件,避免重复触发
public void StopIsUp(){M_Animator.SetBool("IsUp",false);}
//调整投掷角度的函数
private void AdjustTheAngle()
{
if(canAdjustTheAngle)//如果玩家能调整角度
{
throwingAngle += throwingAngleDir//则让现在的抛出角度加上变化的速度
* indexRecoder.rateOfChangeOfThrowingAngle//乘以变化的速率
* Time.deltaTime;//使其与时间无关
Debug.DrawLine(throwOffset.position,
new Vector3(transform.position.x + 100*Mathf.Cos(throwingAngle),
transform.position.y + 100*Mathf.Sin(throwingAngle),
transform.position.z),
Color.red);
DrawPath();
}
}
public void ChangeInputMapToNull()
{
playerInput.SwitchCurrentActionMap("NullMap");
}
public void ChangeInputMapToNormal()
{
playerInput.SwitchCurrentActionMap("PlayerNormal");
}
//当玩家在修电报机地图下按下交互键触发
public void OnComfirm(InputAction.CallbackContext context)
{
if(context.started) catched.Comfirm();
}
//当水平轴有输入
public void OnMoveHorizons(InputAction.CallbackContext context)
{
float value = context.ReadValue<float>();
M_Animator.SetBool("IsWalking",true);
//输入只有对移动方向和面部朝向的更改
if(value > 0)
{
inputDir = 1;
faceDir = 1;
}
else if(value < 0)
{
inputDir = -1;
faceDir = -1;
}
else {inputDir = 0;
M_Animator.SetBool("IsWalking",false);}
//修改面部朝向
transform.localScale = new Vector3(
Mathf.Abs(transform.localScale.x)*faceDir,
transform.localScale.y,
transform.localScale.z);
// //修改灰尘朝向
// runFootsDust.transform.localScale = new Vector3(
// Mathf.Abs(runFootsDust.transform.localScale.x)*faceDir,
// runFootsDust.transform.localScale.y,
// runFootsDust.transform.localScale.z);
//转身时修改默认投掷角度
if(faceDir == -1)throwingAngle = 46f;
else throwingAngle = 45f;
}
private int shouldBePlayedRunSEID = 0;
public void OnRunFootTouched()
{
//跑步动画中脚着地触发
audioPlayer.clip = RunSEs[shouldBePlayedRunSEID % RunSEs.Length];
audioPlayer.volume = 0.2f;
audioPlayer.Play();
shouldBePlayedRunSEID++;
}
private int shouldBePlayedWalkSEID = 0;
public void OnWalkFootTouched()
{
//走路动画中脚着地触发
audioPlayer.clip = walkSEs[shouldBePlayedWalkSEID % walkSEs.Length];
audioPlayer.volume = 0.2f;
audioPlayer.Play();
shouldBePlayedWalkSEID++;
}
//监听投掷按键的函数
public void OnThrow(InputAction.CallbackContext context)
{
if(context.started)//如果按下投掷键,表示可以开始控制角度了
{
canAdjustTheAngle = true;
//动画:进入准备丢的动画
M_Animator.SetBool("ReadyToThrow", true);
}
if(context.canceled)//如果是刚松开投掷键,表示要丢东西了
{
if(throwingState)
{
M_Animator.SetBool("NowThrow",true);//动画:执行丢这个动作
Throw();//如果处于投掷阶段,则触发丢
}
}
}
public void OnQuit(InputAction.CallbackContext context)
{
if(context.started)
{
if(catched != null) catched.Quit();//如果按下退出按钮,则执行捕捉到物体的退出功能
}
}
//如果正处于投掷状态,则退出投掷状态的监听函数
public void OnThrowQuit(InputAction.CallbackContext context){if(throwingState)StartCoroutine("QuitThrowingsState");}
//监听修改投掷角度的函数
public void OnAdjustTheAngle(InputAction.CallbackContext context)
{throwingAngleDir = context.ReadValue<float>();}//把收到的轴的值交给角度变化的大小和方向
//控制投掷相关的具体函数
private void Throw()
{
Rigidbody2D rigidbodyOfMissile = //并且获得这个投掷物身上的刚体组件
Instantiate(missile,throwOffset.position,Quaternion.identity).GetComponent<Rigidbody2D>();//生成一个投掷物
//给这个投掷物赋予速度,由目前的角度决定
rigidbodyOfMissile.velocity = new Vector2(strengthOfThrowing*Mathf.Cos(throwingAngle),
strengthOfThrowing*Mathf.Sin(throwingAngle));
//扔完后退出投掷状态并且重置相关参数
StartCoroutine("QuitThrowingsState");
}
//在投掷物堆中调用,每次呼叫投掷物堆,都针对此堆更新投掷力度
public void ChangeStrengthOfThrowingTo(float num)
{
strengthOfThrowing = num;
}
//进入跑步状态的控制代码
public void OnRun(InputAction.CallbackContext context)
{
if(context.started)//如果刚按下跑步键
{
runSpeedMultiple = indexRecoder.runSpeedMultiple;//把本地的速度倍率变成数值记录器中的倍率
M_Animator.SetBool("IsRunning",true);//播放跑步动画
// runFootsDust.SetActive(true);//播放脚上灰尘粒子特效
}
else if(context.canceled)//如果刚松开跑步键
{
runSpeedMultiple = 1f;//恢复本地速度倍率为1
M_Animator.SetBool("IsRunning",false);//关闭跑步动画
// runFootsDust.SetActive(false);//关闭脚上灰尘粒子特效
}
}
//监听交互按键的函数
public void OnInteraction(InputAction.CallbackContext context)
{
if(context.started)
{
//可交互对象都有UI界面。当按下交互键后显示交互界面
if(catched != null)
{
//触发交互函数,在具象物体中重写这个虚拟功能
catched.OnCall();
//如果捕捉对象是电话线
if(catched != null && catched.tag == "电话线")
{
//获取其电话线组件,如果其未修好,则执行修理动画
if(!catched.GetComponent<TelephoneLine>().HasTheBePrepared())
M_Animator.SetBool("IsReparing", true);
//播放修复电话线音效
audioPlayer.clip = ReapareTelephoneLineSE;
audioPlayer.volume = 0.8f;
audioPlayer.loop = true;
audioPlayer.Play();
}
}
}
if(context.canceled)
{
//可交互对象电话线比较特殊,需要额外检测按钮松开的瞬间
if(catched != null && catched.tag == "电话线")
{
catched.StopRepareTheTelephoneLine();
//如果捕捉对象是电话线,停止修电话线动画
if(catched.tag == "电话线") M_Animator.SetBool("IsReparing", false);
//停止修复电话线音效
audioPlayer.Stop();
audioPlayer.loop = false;
}
}
}
//当修好了一个电话线,强制打断修电话线动画
public void HasReparedATelephone()
{
M_Animator.SetBool("IsReparing", false);
}
//监听打电码的函数
public void OnCoding(InputAction.CallbackContext context)
{
if(context.started)
{
machineAudio.Play();
//如果刚按下打码把电报机UI图片的把手替换成按下的
catched.ChangeHandleTo(true);
}
if(context.canceled)
{
machineAudio.Stop();
//如果刚松开打码把电报机UI图片的把手换成松开的
catched.ChangeHandleTo(false);
//根据按下期间时长发送打出来的码给电报机
if(catched != null)
{
if(context.duration < indexRecoder.dotRoLineTime)//如果小于界限时间
{
catched.Coding(".");
}
else
{
catched.Coding("-");
}
}
}
}
//动画内调用,当玩家掉下坑后,主要用来播放音效
public void OnDropTheHole()
{
audioPlayer.volume = 0.8f;
audioPlayer.clip = dropHoleSE;
audioPlayer.Play();
}
//动画内调用,当玩家爬上坑后,主要用来播放音效
public void OnOutTheHole()
{
audioPlayer.volume = 0.8f;
audioPlayer.clip = upHoleSE;
audioPlayer.Play();
}
//使自身进入投掷状态的函数
public void EnterThrowingState()
{
throwingState = true;//修改自身记录状态变量,表示正式进入投掷状态
//1.切换操控地图
playerInput.SwitchCurrentActionMap("PlayerInThrowing");
//2.动画相关
M_Animator.SetBool("throwingState",true);//使自身进入捡石动画
}
//退出投掷状态的时候
public IEnumerator QuitThrowingsState()
{
throwingState = false;//改变自身标记
playerInput.SwitchCurrentActionMap("PlayerNormal");//修改自身操控地图
if(faceDir == 1) throwingAngle = 45f;//恢复投掷角度到45°
else throwingAngle = 46f;
canAdjustTheAngle = false;//可修改角度标记改为false
GetComponent<LineRenderer>().enabled = false;//别画线了
//关闭动画条件
M_Animator.SetBool("throwingState",false);
M_Animator.SetBool("ReadyToThrow",false);
//为了解决问题需要到下一帧关闭丢出动画指令
yield return new WaitForEndOfFrame();
M_Animator.SetBool("NowThrow",false);
}
//播放上下楼动画的函数,在楼梯边的触发器调用
public void PlayDownStairAnimation(){M_Animator.SetBool("IsDownStair",true);}
public void PlayUpStairAnimation(){}
//外部调用,让玩家转身
public void TurnAround()
{
transform.localScale = new Vector3(
transform.localScale.x*-1,
transform.localScale.y,
transform.localScale.z);//让玩家转身
}
public void YouAreShooting()
{
// 当玩家被射中时调用
M_Animator.SetBool("IsShootDead",true);
StartCoroutine("StopShootingAnimation");//此帧结束后关闭死亡动画条件
}
private IEnumerator StopShootingAnimation()
{
yield return new WaitForSeconds(0.1f);
M_Animator.SetBool("IsShootDead",false);
}
public void YouAreCovered(){isCovered = true;}
public void YouAreLosingCover(){isCovered = false;}
public bool AreYouCovered(){return isCovered;}
//绘制投掷曲线的函数,非常🐂
public void DrawPath()
{
//
LineRenderer line = GetComponent<LineRenderer>();//获取组件
line.enabled = true;
int segmentCount = 18;//定义点数
line.positionCount = segmentCount;//传入点数
float gravity=9.8f*2;//定义重力常量
Vector2 fireOffset = new Vector2(throwOffset.position.x - transform.position.x,
throwOffset.position.y - transform.position.y);
Vector2[] segments = new Vector2[segmentCount];//定义二维向量数组用来存15个点的位置
segments[0].Set(transform.position.x + fireOffset.x, transform.position.y + fireOffset.y);//定义起点
line.SetPosition(0, segments[0]);//把起点位置传入线的起点
for (int i = 1; i < segmentCount; i++)//根据时间、循环确定点的位置
{
float time = i * Time.fixedDeltaTime * 5;//类似时间间隔的定义也就是抛物线上的x多久取值一次
segments[i].x = transform.position.x + //自身位置的x
fireOffset.x + //发射偏移量的x
time * strengthOfThrowing * Mathf.Cos(throwingAngle);//水平方向位移 = v*t
segments[i].y = (transform.position.y + fireOffset.y + //自身位置的y
time * strengthOfThrowing * Mathf.Sin(throwingAngle) +
(0.5f * gravity * time * time)*-1);//垂直方向位移 = vt + 1/2 * g * t^2
line.SetPosition(i, segments[i]); //把算好的点传入线的点集
}
}
}