SAIPO bf213bea54 优化游戏特效及制作游戏音效
优化:
1.基督小怪的shader添加完毕,但是小怪的闪电似乎有bug,见末尾bug集合
2.给炸弹爆炸加入了粒子特效
3.优化了死亡的屏幕后特效,现在做到了只有黑白区域才会渲染死亡鬼魂的效果

音效:
1.制作了地藏的全部音效
2.制作了特洛伊木马的全部音效
3.制作了以撒的全部音效
4.制作了玩家 跳跃,挥锤子,扔镰刀,受击,死亡,与击中敌人的音效,目前还缺少交互音效
5.制作了爱欲品的抱人音效
6.制作了所有与爆炸相关的音效

音效大体上已经制作完毕,逻辑也已经写完了
如果有不合适的音效改起来还算容易

问题:
1.目前在交互时(对话,看牌子),玩家可以进行挥砍和跳跃
2.基督石像的雷击效果只有一半不知道是不是bug
3.基督石像我没有找到他的受击函数,所以他的受击音效我没有制作

下班,绷不住了,真就干了后半夜。
2021-12-28 05:01:18 +08:00

258 lines
9.2 KiB
C#
Raw Permalink 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 Sirenix.OdinInspector;
/// <summary>
/// 爱欲品类,继承自三关都有的那个小怪类
/// </summary>
public class AiYuPin : NormalEnemy
{
// _____ _ _ _
// | __ \ | | | (_)
// | |__) | _| |__ | |_ ___
// | ___/ | | | '_ \| | |/ __|
// | | | |_| | |_) | | | (__
// |_| \__,_|_.__/|_|_|\___|
/// <summary>
/// 爱欲品抓住玩家后贴在玩家身上时的位置偏移量
/// </summary>
[FoldoutGroup("爱欲品")][Header("爬到玩家身上的时候的位置偏移量")]
public Vector3 catchOffset;
/// <summary>
/// 玩家挣脱爱欲品需要多少次方向转换操作
/// </summary>
[Header("玩家挣脱爱欲品需要多少次方向转换操作")][FoldoutGroup("爱欲品")]
public int breakFreeCount;
/// <summary>
/// 玩家挣脱爱欲品还需要多少次方向转换操作
/// </summary>
[Header("玩家挣脱爱欲品还需要多少次方向转换操作")][FoldoutGroup("爱欲品")][ReadOnly]
public int breakFreeCountLeft;
/// <summary>
/// 这个爱欲品有主人吗?也就是地藏
/// </summary>
[HideInInspector]
public bool hasOwner;
/// <summary>
/// 打死后掉落的钱的预制体
/// </summary>
[Header("打死后掉落的钱的预制体")][FoldoutGroup("预制体")]
public GameObject coinObj;
// _____ _ _
// | __ \ (_) | |
// | |__) | __ ___ ____ _| |_ ___
// | ___/ '__| \ \ / / _` | __/ _ \
// | | | | | |\ V / (_| | || __/
// |_| |_| |_| \_/ \__,_|\__\___|
/// <summary>
/// 爱欲品发动Seek后追击的目标
/// </summary>
//虽说是目标,但爱欲品只会抓玩家吧。直接初始化成玩家了
protected Transform target;
/// <summary>
/// 记录当前自己是否抓着玩家
/// </summary>
private bool isCatching = false;
private Animator aiYuPinAnimator;
// _____ _ _ ____ _
// / ____| | | | _ \ | |
// | | __ _| | | |_) | __ _ ___| | __
// | | / _` | | | _ < / _` |/ __| |/ /
// | |___| (_| | | | |_) | (_| | (__| <
// \_____\__,_|_|_|____/ \__,_|\___|_|\_\
void Update(){
//如果在Seek状态则Seek
if(state == State.seek) Seek(target);
if(isCatching){
//将自身位置和玩家位置同步但是需要一个附身offset二维向量
//因为玩家的图片不在游戏物体的中心
transform.position = target.position + catchOffset;
}
}
// _ _ _
// | \ | | | |
// | \| | ___ _ __ _ __ ___ __ _| |
// | . ` |/ _ \| '__| '_ ` _ \ / _` | |
// | |\ | (_) | | | | | | | | (_| | |
// |_| \_|\___/|_| |_| |_| |_|\__,_|_|
protected override void Init()
{
//找到必要的游戏物体和组件
aiYuPinAnimator = GetComponent<Animator>();
//初始化基础属性
base.Init();
//初始化爱欲品属性
breakFreeCountLeft = breakFreeCount;//初始化挣脱需要的操作次数
target = FindObjectOfType<MyPlayer>().transform;//初始化追踪目标为玩家
if(FindObjectOfType<DiZang>()) hasOwner = true;
}
/// <summary>
/// 控制爱欲品追踪传入的Transform每帧调用一次
/// </summary>
/// <param name="target">要追踪的目标的transform组件</param>
protected virtual void Seek(Transform target){
Vector3 moveDir = (target.transform.position - transform.position).normalized;
// //给刚体添加位移
// m_rigidbody.position += (Vector2)moveDir * speed * Time.deltaTime * Vector2.right;
//给刚体以速度
if(canBeHit)
m_rigidbody.velocity = new Vector2(
((moveDir.x > 0) ? 1 : -1) * speed,
m_rigidbody.velocity.y
);
//将面部朝向与速度同步
transform.rotation = Quaternion.
Euler
(transform.rotation.x,
((target.position.x - transform.position.x > 0) ? 0:-180),
transform.rotation.z);
}
/// <summary>
/// 制造一个特殊的钱,用来塞钱的那种
/// </summary>
private void MakeAnCoin(){
GameObject coin = Instantiate(
coinObj,
transform.position,
Quaternion.identity
);
coin.GetComponent<Rigidbody2D>().velocity = new Vector2(
Random.Range(-1f,1f),
Random.Range(-1f,1f)
).normalized * (5f);
}
// ______ _
// | ____| | |
// | |____ _____ _ __ | |_
// | __\ \ / / _ \ '_ \| __|
// | |___\ V / __/ | | | |_
// |______\_/ \___|_| |_|\__|
/// <summary>
/// 当爱欲品发现玩家
/// </summary>
public override void OnFindThePlayer(Transform target){
//如果没死
if(state == State.wander)
{
//标记自身状态
state = State.seek;
//赋予自身目标以玩家Transform
this.target = target;
//关闭巡逻动画
doTweenPath.DOPause();
}
}
/// <summary>
/// 当爱欲品抓住玩家
/// </summary>
protected override void OnTouchThePlayer(MyPlayer player)
{
//如果玩家没有被抓住,才执行抓住
if(!player.isCatching){
//通知玩家,你被爱欲品附身了
player.BeCatchedByAiYuPin(this);
//暂停Path动画
doTweenPath.DOPause();
//改变自身状态为ATK
state = State.atk;
//关闭自身碰撞体,因为要贴在玩家身上
GetComponent<BoxCollider2D>().enabled = false;
//将自身位置和玩家位置同步但是需要一个附身offset二维向量
//因为玩家的图片不在游戏物体的中心
transform.position = target.position + catchOffset;
//暂时清空重力系数
m_rigidbody.gravityScale = 0;
//清除一下刚体速度,不然怪物可能被创飞
m_rigidbody.velocity = Vector2.zero;
//清除角动量,不然可能会转起来
m_rigidbody.angularVelocity = 0;
//标记自身正抓着玩家
isCatching = true;
//执行抓住动画
if(aiYuPinAnimator != null) aiYuPinAnimator.SetBool("isBeHit",false);
if(aiYuPinAnimator != null) aiYuPinAnimator.SetBool("isATK",true);
}
//如果玩家正被抓着则执行父类——普通小怪的Touch即击飞玩家
else{
base.OnTouchThePlayer(player);
//同时,清空当前附身着的爱欲品的挣脱次数
player.catingAiYuPin.breakFreeCountLeft = breakFreeCount;
}
}
/// <summary>
/// 当爱欲品被攻击了
/// </summary>
/// <param name="hitMethod">攻击方式</param>
/// <param name="hitDir">攻击来袭方向</param>
public override void OnBeHit(MyPlayer.AtkMethod hitMethod, int hitDir){
attackAudio.Play();
//被打飞在着地前都不会挨打了
canBeHit = false;
//执行被击飞、死亡检查等事宜
base.OnBeHit(hitMethod, hitDir);
//爱欲品会额外触发发现玩家事件
target = FindObjectOfType<MyPlayer>().transform;//将目标指向玩家
OnFindThePlayer(target);//触发发现玩家事件
//执行受击动画
if(aiYuPinAnimator != null) aiYuPinAnimator.SetBool("isBeHit",true);
}
//原先会触发自动返回记录起点,但是不能,所以重写空的重新着地事件
public override void OnRetouchedTheGround(){
canBeHit = true;
//解除受击动画
if(aiYuPinAnimator != null) aiYuPinAnimator.SetBool("isBeHit",false);
}
/// <summary>
/// 完全挣脱的时候触发
/// </summary>
protected void OnBreakFreeCompletely(){
//恢复一下抓到玩家的时候消除的重力系数
m_rigidbody.gravityScale = 1;
//随机一个死亡面部朝向
deadDir = (Random.Range(-1f,1f) > 0) ? 1: -1;
//标记自身不再抓着玩家
isCatching = false;
//触发死亡事件
OnDead();
//给一个击飞
BeHitToFly((Random.Range(-1f,1f) > 0) ? 1: -1);
//通知玩家
FindObjectOfType<MyPlayer>().BreakFreeCompletely();
}
public override void OnDead(){
//停止攻击动画,执行受击动画
if(aiYuPinAnimator != null) aiYuPinAnimator.SetBool("isATK",false);
if(aiYuPinAnimator != null) aiYuPinAnimator.SetBool("isBeHit",true);
base.OnDead();
if(
hasOwner &&
target.GetComponent<MyPlayer>().specialMoneyCount == 0 &&
FindObjectOfType<Coin>() == null
)MakeAnCoin();
}
/// <summary>
/// 玩家尝试挣脱的时候触发这个
/// </summary>
public void OnBreakFree(){
if(--breakFreeCountLeft <= 0) OnBreakFreeCompletely();
}
}