religion/Assets/Scripts/AiYuPin.cs
Roman 5b2e3633ab 任务:搭建基本的系统
1.替换动画源图片为攻击加长版
(*:新建动画“被击飞”并完成状态机逻辑
(*:删除旧动画源图片素材减小项目体积
*:修复攻击动画卡手问题
*:修复被击飞后朝向影响击飞结果的Bug

2.编写佛教小怪逻辑
(1.继承自NormalEnemy(*:与原备注不同,因为后期我发现用NormalEnemy更加合适更加简单)
(2.与普通小怪一样,默认状态会巡逻
(3.当玩家进入感知范围,触发Seek
(4.当玩家创到怪物,触发Atk
(*:改变自身状态为ATK
(*:关闭自身碰撞体,因为要贴在玩家身上
(*:将自身位置和玩家位置同步,但是需要一个附身offset二维向量,因为玩家的图片不在游戏物体的中心
(*:通知玩家,你被爱欲品附身了
(5.当怪物收到伤害,触发Seek
(*:我决定后期根据具体地形完善爱欲品的Seek函数
(6.编写完全挣脱事件
(*:触发死亡事件
(*:死亡后给予随机方向的击飞和旋转
(*:添加public变量breakFreeCount,代表挣脱需要触发多少次方向变换
(*:添加public变量breakFreeCountLeft,代表现在还需要方向变换多少次才能挣脱
(7.添加挣脱行为事件,从player传来,减一点Left并且判断是否完全挣脱,若是则执行完全挣脱事件
3.整理脚本分层,添加摘要和注释

下班,明天写玩家挣脱逻辑和被抓逻辑
🥱🥱🥱🥱🥱🥱🥱🥱🥱🥱🥱🥱🥱🥱🥱🥱🥱🥱
2021-12-03 01:23:07 +08:00

170 lines
6.0 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 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;
// _____ _ _
// | __ \ (_) | |
// | |__) | __ ___ ____ _| |_ ___
// | ___/ '__| \ \ / / _` | __/ _ \
// | | | | | |\ V / (_| | || __/
// |_| |_| |_| \_/ \__,_|\__\___|
/// <summary>
/// 爱欲品发动Seek后追击的目标
/// </summary>
//虽说是目标,但爱欲品只会抓玩家吧。直接初始化成玩家了
protected Transform target;
// _____ _ _ ____ _
// / ____| | | | _ \ | |
// | | __ _| | | |_) | __ _ ___| | __
// | | / _` | | | _ < / _` |/ __| |/ /
// | |___| (_| | | | |_) | (_| | (__| <
// \_____\__,_|_|_|____/ \__,_|\___|_|\_\
void Update(){
//如果在Seek状态则Seek
if(state == State.seek) Seek(target);
}
// _ _ _
// | \ | | | |
// | \| | ___ _ __ _ __ ___ __ _| |
// | . ` |/ _ \| '__| '_ ` _ \ / _` | |
// | |\ | (_) | | | | | | | | (_| | |
// |_| \_|\___/|_| |_| |_| |_|\__,_|_|
protected override void Init()
{
//初始化基础属性
base.Init();
//初始化爱欲品属性
breakFreeCountLeft = breakFreeCount;//初始化挣脱需要的操作次数
target = FindObjectOfType<MyPlayer>().transform;//初始化追踪目标为玩家
}
/// <summary>
/// 控制爱欲品追踪传入的Transform每帧调用一次
/// </summary>
/// <param name="target">要追踪的目标的transform组件</param>
protected void Seek(Transform target){
//注意需要修改。此时会给予爱欲品向上的速度但Seek只需要左右的速度
Vector3 moveDir = (target.transform.position - transform.position).normalized;
//给刚体添加位移
m_rigidbody.position += (Vector2)moveDir * speed * Time.deltaTime;
//将面部朝向与速度同步
transform.rotation = Quaternion.
Euler
(transform.rotation.x,
((target.position.x - transform.position.x > 0) ? 0:-180),
transform.rotation.z);
}
// ______ _
// | ____| | |
// | |____ _____ _ __ | |_
// | __\ \ / / _ \ '_ \| __|
// | |___\ V / __/ | | | |_
// |______\_/ \___|_| |_|\__|
/// <summary>
/// 当爱欲品发现玩家
/// </summary>
protected override void OnFindThePlayer(Transform target){
//如果没死
if(state != State.dead)
{
//标记自身状态
state = State.seek;
//赋予自身目标以玩家Transform
this.target = target;
//关闭巡逻动画
doTweenPath.DOPause();
}
}
/// <summary>
/// 当爱欲品抓住玩家
/// </summary>
protected override void OnTouchThePlayer(MyPlayer player)
{
//改变自身状态为ATK
state = State.atk;
//关闭自身碰撞体,因为要贴在玩家身上
GetComponent<BoxCollider2D>().enabled = false;
//将自身位置和玩家位置同步但是需要一个附身offset二维向量
//因为玩家的图片不在游戏物体的中心
transform.position = target.position + catchOffset;
//通知玩家,你被爱欲品附身了
player.BeCatchedByAiYuPin(this);
//暂时清空重力系数
m_rigidbody.gravityScale = 0;
}
/// <summary>
/// 当爱欲品被攻击了
/// </summary>
/// <param name="hitMethod">攻击方式</param>
/// <param name="hitDir">攻击来袭方向</param>
public override void OnBeHit(MyPlayer.AtkMethod hitMethod, int hitDir){
//爱欲品会额外触发发现玩家事件
target = FindObjectOfType<MyPlayer>().transform;//将目标指向玩家
OnFindThePlayer(target);//触发发现玩家事件
//执行被击飞、死亡检查等事宜
base.OnBeHit(hitMethod, hitDir);
}
//原先会触发自动返回记录起点,但是不能,所以重写空的重新着地事件
protected override void OnRetouchedTheGround(){}
/// <summary>
/// 完全挣脱的时候触发
/// </summary>
protected void OnBreakFreeCompletely(){
//恢复一下抓到玩家的时候消除的重力系数
m_rigidbody.gravityScale = 1;
//随机一个死亡面部朝向
deadDir = (Random.Range(-1f,1f) > 0) ? 1: -1;
//触发死亡事件
OnDead();
//给一个击飞
BeHitToFly((Random.Range(-1f,1f) > 0) ? 1: -1);
}
/// <summary>
/// 玩家尝试挣脱的时候触发这个
/// </summary>
[ContextMenu("挣脱")]
protected void OnBreakFree(){
if(--breakFreeCountLeft <= 0) OnBreakFreeCompletely();
}
}