初始化仓库
This commit is contained in:
@@ -0,0 +1,9 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 58efe0589d7e90f498c8bcbbf94c6be4
|
||||
folderAsset: yes
|
||||
timeCreated: 1528026151
|
||||
licenseType: Pro
|
||||
DefaultImporter:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,53 @@
|
||||
//------------------------------------------------------------
|
||||
// Game Framework
|
||||
// Copyright © 2013-2021 Jiang Yin. All rights reserved.
|
||||
// Homepage: https://gameframework.cn/
|
||||
// Feedback: mailto:ellan@gameframework.cn
|
||||
//------------------------------------------------------------
|
||||
|
||||
using System;
|
||||
using Definition.Enum;
|
||||
using StarForce;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Entity.EntityData
|
||||
{
|
||||
[Serializable]
|
||||
public abstract class AccessoryObjectData : EntityDataBase
|
||||
{
|
||||
[SerializeField]
|
||||
private int m_OwnerId = 0;
|
||||
|
||||
[SerializeField]
|
||||
private CampType m_OwnerCamp = CampType.Unknown;
|
||||
|
||||
public AccessoryObjectData(int entityId, int typeId, int ownerId, CampType ownerCamp)
|
||||
: base(entityId, typeId)
|
||||
{
|
||||
m_OwnerId = ownerId;
|
||||
m_OwnerCamp = ownerCamp;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 拥有者编号。
|
||||
/// </summary>
|
||||
public int OwnerId
|
||||
{
|
||||
get
|
||||
{
|
||||
return m_OwnerId;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 拥有者阵营。
|
||||
/// </summary>
|
||||
public CampType OwnerCamp
|
||||
{
|
||||
get
|
||||
{
|
||||
return m_OwnerCamp;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 83cb841b7411a844581691d5547bf866
|
||||
timeCreated: 1528026151
|
||||
licenseType: Pro
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,71 @@
|
||||
//------------------------------------------------------------
|
||||
// Game Framework
|
||||
// Copyright © 2013-2021 Jiang Yin. All rights reserved.
|
||||
// Homepage: https://gameframework.cn/
|
||||
// Feedback: mailto:ellan@gameframework.cn
|
||||
//------------------------------------------------------------
|
||||
|
||||
using System;
|
||||
using Definition.Enum;
|
||||
using StarForce;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Entity.EntityData
|
||||
{
|
||||
[Serializable]
|
||||
public class BulletData : EntityDataBase
|
||||
{
|
||||
[SerializeField]
|
||||
private int m_OwnerId = 0;
|
||||
|
||||
[SerializeField]
|
||||
private CampType m_OwnerCamp = CampType.Unknown;
|
||||
|
||||
[SerializeField]
|
||||
private int m_Attack = 0;
|
||||
|
||||
[SerializeField]
|
||||
private float m_Speed = 0f;
|
||||
|
||||
public BulletData(int entityId, int typeId, int ownerId, CampType ownerCamp, int attack, float speed)
|
||||
: base(entityId, typeId)
|
||||
{
|
||||
m_OwnerId = ownerId;
|
||||
m_OwnerCamp = ownerCamp;
|
||||
m_Attack = attack;
|
||||
m_Speed = speed;
|
||||
}
|
||||
|
||||
public int OwnerId
|
||||
{
|
||||
get
|
||||
{
|
||||
return m_OwnerId;
|
||||
}
|
||||
}
|
||||
|
||||
public CampType OwnerCamp
|
||||
{
|
||||
get
|
||||
{
|
||||
return m_OwnerCamp;
|
||||
}
|
||||
}
|
||||
|
||||
public int Attack
|
||||
{
|
||||
get
|
||||
{
|
||||
return m_Attack;
|
||||
}
|
||||
}
|
||||
|
||||
public float Speed
|
||||
{
|
||||
get
|
||||
{
|
||||
return m_Speed;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 16371cc6e2112964d8b5bf7400c862cd
|
||||
timeCreated: 1528026152
|
||||
licenseType: Pro
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,18 @@
|
||||
namespace Entity.EntityData
|
||||
{
|
||||
public class CoinData : EntityDataBase
|
||||
{
|
||||
private int _value;
|
||||
|
||||
public CoinData(int value, int entityId, int typeId) : base(entityId, typeId)
|
||||
{
|
||||
_value = value;
|
||||
}
|
||||
|
||||
public int Value
|
||||
{
|
||||
get => _value;
|
||||
set => _value = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d9caee22d67a42018113acc77155d6ba
|
||||
timeCreated: 1770292597
|
||||
@@ -0,0 +1,33 @@
|
||||
//------------------------------------------------------------
|
||||
// Game Framework
|
||||
// Copyright © 2013-2021 Jiang Yin. All rights reserved.
|
||||
// Homepage: https://gameframework.cn/
|
||||
// Feedback: mailto:ellan@gameframework.cn
|
||||
//------------------------------------------------------------
|
||||
|
||||
using System;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Entity.EntityData
|
||||
{
|
||||
[Serializable]
|
||||
public class EffectData : EntityDataBase
|
||||
{
|
||||
[SerializeField]
|
||||
private float m_KeepTime = 0f;
|
||||
|
||||
public EffectData(int entityId, int typeId)
|
||||
: base(entityId, typeId)
|
||||
{
|
||||
m_KeepTime = 3f;
|
||||
}
|
||||
|
||||
public float KeepTime
|
||||
{
|
||||
get
|
||||
{
|
||||
return m_KeepTime;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e5b93dcbe30421a429c196bda0af31ed
|
||||
timeCreated: 1528026152
|
||||
licenseType: Pro
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 611437bd292819b439512f684e13c7e3
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,56 @@
|
||||
using System;
|
||||
using DataTable;
|
||||
using Definition.Enum;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Entity.EntityData
|
||||
{
|
||||
[Serializable]
|
||||
public class EnemyData : TargetableObjectData
|
||||
{
|
||||
[SerializeField] private float _speedBase = 0;
|
||||
|
||||
[SerializeField] private int _dropCoin = 0;
|
||||
|
||||
[SerializeField] private int _dropExp = 0;
|
||||
|
||||
[SerializeField] private float _dropPercent = 0;
|
||||
|
||||
public EnemyData(int entityId, int typeId) : base(
|
||||
entityId, typeId, CampType.Enemy)
|
||||
{
|
||||
DREnemy enemyRow = GameEntry.DataTable.GetDataTableRow<DREnemy>(typeId);
|
||||
MaxHealthBase = enemyRow.MaxHealth;
|
||||
SpeedBase = enemyRow.Speed;
|
||||
DropCoin = enemyRow.DropCoin;
|
||||
DropExp = enemyRow.DropExp;
|
||||
DropPercent = enemyRow.DropPercent;
|
||||
}
|
||||
|
||||
public override int MaxHealthBase { get; }
|
||||
|
||||
public float SpeedBase
|
||||
{
|
||||
get => _speedBase;
|
||||
set => _speedBase = value;
|
||||
}
|
||||
|
||||
public int DropCoin
|
||||
{
|
||||
get => _dropCoin;
|
||||
set => _dropCoin = value;
|
||||
}
|
||||
|
||||
public int DropExp
|
||||
{
|
||||
get => _dropExp;
|
||||
set => _dropExp = value;
|
||||
}
|
||||
|
||||
public float DropPercent
|
||||
{
|
||||
get => _dropPercent;
|
||||
set => _dropPercent = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1b802c30cc274e04929b8659ec631e84
|
||||
timeCreated: 1768890974
|
||||
@@ -0,0 +1,62 @@
|
||||
//------------------------------------------------------------
|
||||
// Game Framework
|
||||
// Copyright © 2013-2021 Jiang Yin. All rights reserved.
|
||||
// Homepage: https://gameframework.cn/
|
||||
// Feedback: mailto:ellan@gameframework.cn
|
||||
//------------------------------------------------------------
|
||||
|
||||
using System;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Entity.EntityData
|
||||
{
|
||||
[Serializable]
|
||||
public abstract class EntityDataBase
|
||||
{
|
||||
[SerializeField]
|
||||
private int m_Id = 0;
|
||||
|
||||
[SerializeField]
|
||||
private int m_TypeId = 0;
|
||||
|
||||
[SerializeField]
|
||||
private Vector3 m_Position = Vector3.zero;
|
||||
|
||||
[SerializeField]
|
||||
private Quaternion m_Rotation = Quaternion.identity;
|
||||
|
||||
public EntityDataBase(int entityId, int typeId)
|
||||
{
|
||||
m_Id = entityId;
|
||||
m_TypeId = typeId;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 实体编号。
|
||||
/// </summary>
|
||||
public int Id => m_Id;
|
||||
|
||||
/// <summary>
|
||||
/// 实体类型编号。
|
||||
/// </summary>
|
||||
public int TypeId => m_TypeId;
|
||||
|
||||
/// <summary>
|
||||
/// 实体位置。
|
||||
/// </summary>
|
||||
public Vector3 Position
|
||||
{
|
||||
get => m_Position;
|
||||
set => m_Position = value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 实体朝向。
|
||||
/// </summary>
|
||||
public Quaternion Rotation
|
||||
{
|
||||
get => m_Rotation;
|
||||
set => m_Rotation = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: afb91fe3ed8105e4a96b7bd5917ecc2b
|
||||
timeCreated: 1528026152
|
||||
licenseType: Pro
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,18 @@
|
||||
namespace Entity.EntityData
|
||||
{
|
||||
public class ExpData : EntityDataBase
|
||||
{
|
||||
private int _value;
|
||||
|
||||
public ExpData(int value, int entityId, int typeId) : base(entityId, typeId)
|
||||
{
|
||||
_value = value;
|
||||
}
|
||||
|
||||
public int Value
|
||||
{
|
||||
get => _value;
|
||||
set => _value = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e0f6c8e117da49f1ad04fd8810882043
|
||||
timeCreated: 1770292932
|
||||
@@ -0,0 +1,19 @@
|
||||
using System;
|
||||
using DataTable;
|
||||
using Definition.Enum;
|
||||
|
||||
namespace Entity.EntityData
|
||||
{
|
||||
[Serializable]
|
||||
public class PlayerData : TargetableObjectData
|
||||
{
|
||||
private int _maxExp;
|
||||
|
||||
public PlayerData(int entityId, int typeId) : base(entityId, typeId, CampType.Player)
|
||||
{
|
||||
MaxHealthBase = MaxHealthBase;
|
||||
}
|
||||
|
||||
public override int MaxHealthBase { get; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b69d3168ac4f442994f8dc4d906daa60
|
||||
timeCreated: 1768890638
|
||||
@@ -0,0 +1,40 @@
|
||||
//------------------------------------------------------------
|
||||
// Game Framework
|
||||
// Copyright © 2013-2021 Jiang Yin. All rights reserved.
|
||||
// Homepage: https://gameframework.cn/
|
||||
// Feedback: mailto:ellan@gameframework.cn
|
||||
//------------------------------------------------------------
|
||||
|
||||
using System;
|
||||
using Definition.Enum;
|
||||
using StarForce;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Entity.EntityData
|
||||
{
|
||||
[Serializable]
|
||||
public abstract class TargetableObjectData : EntityDataBase
|
||||
{
|
||||
[SerializeField]
|
||||
private CampType _camp = CampType.Unknown;
|
||||
|
||||
public TargetableObjectData(int entityId, int typeId, CampType camp)
|
||||
: base(entityId, typeId)
|
||||
{
|
||||
_camp = camp;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 角色阵营。
|
||||
/// </summary>
|
||||
public CampType Camp => _camp;
|
||||
|
||||
/// <summary>
|
||||
/// 最大生命。
|
||||
/// </summary>
|
||||
public abstract int MaxHealthBase
|
||||
{
|
||||
get;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f866c15cf3f2a45429251d4a66f70c77
|
||||
timeCreated: 1528026152
|
||||
licenseType: Pro
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d8b2591453b7f0841940c8e45528f465
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,49 @@
|
||||
using System;
|
||||
using DataTable;
|
||||
using Definition.DataStruct;
|
||||
using Definition.Enum;
|
||||
|
||||
namespace Entity.EntityData
|
||||
{
|
||||
[Serializable]
|
||||
public class WeaponData : AccessoryObjectData
|
||||
{
|
||||
private DRWeapon _drWeapon;
|
||||
|
||||
public WeaponData(int entityId, int typeId, int ownerId, CampType ownerCamp)
|
||||
: base(entityId, typeId, ownerId, ownerCamp)
|
||||
{
|
||||
_drWeapon = GameEntry.DataTable.GetDataTableRow<DRWeapon>(TypeId);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 攻击力。
|
||||
/// </summary>
|
||||
public int Attack => _drWeapon.Attack;
|
||||
|
||||
/// <summary>
|
||||
/// 攻击间隔。
|
||||
/// </summary>
|
||||
public float Cooldown => _drWeapon.Cooldown;
|
||||
|
||||
/// <summary>
|
||||
/// 攻击范围。
|
||||
/// </summary>
|
||||
public float AttackRange => _drWeapon.AttackRange;
|
||||
|
||||
/// <summary>
|
||||
/// 攻击音效。
|
||||
/// </summary>
|
||||
public int AttackSoundId => _drWeapon.AttackSoundId;
|
||||
|
||||
/// <summary>
|
||||
/// 额外参数。
|
||||
/// </summary>
|
||||
public string Params => _drWeapon.Pramas;
|
||||
|
||||
/// <summary>
|
||||
/// 额外属性。
|
||||
/// </summary>
|
||||
public StatModifier[] Modifiers => _drWeapon.Modifiers;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e813e3219579f834d8e619c17a8083d4
|
||||
timeCreated: 1528026153
|
||||
licenseType: Pro
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,12 @@
|
||||
using Definition.Enum;
|
||||
|
||||
namespace Entity.EntityData
|
||||
{
|
||||
public class WeaponKnifeData : WeaponData
|
||||
{
|
||||
public WeaponKnifeData(int entityId, int typeId, int ownerId, CampType ownerCamp) : base(entityId, typeId,
|
||||
ownerId, ownerCamp)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: da25d8e0669f0194d8f56f4283c67b38
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,143 @@
|
||||
//------------------------------------------------------------
|
||||
// Game Framework
|
||||
// Copyright © 2013-2021 Jiang Yin. All rights reserved.
|
||||
// Homepage: https://gameframework.cn/
|
||||
// Feedback: mailto:ellan@gameframework.cn
|
||||
//------------------------------------------------------------
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Definition;
|
||||
using Entity.EntityData;
|
||||
using UnityGameFramework.Runtime;
|
||||
using DataTable;
|
||||
using Definition.Enum;
|
||||
using Game.Utility;
|
||||
|
||||
namespace Entity
|
||||
{
|
||||
public static class EntityExtension
|
||||
{
|
||||
// 关于 EntityId 的约定:
|
||||
// 0 为无效
|
||||
// 正值用于和服务器通信的实体(如玩家角色、NPC、怪等,服务器只产生正值)
|
||||
// 负值用于本地生成的临时实体(如特效、FakeObject等)
|
||||
private static int s_SerialId = -10;
|
||||
|
||||
private const string EntityNamespace = "Entity.";
|
||||
private static Dictionary<string, Type> _typeDict;
|
||||
|
||||
static EntityExtension()
|
||||
{
|
||||
_typeDict = new Dictionary<string, Type>();
|
||||
}
|
||||
|
||||
public static EntityBase GetGameEntity(this EntityComponent entityComponent, int entityId)
|
||||
{
|
||||
UnityGameFramework.Runtime.Entity entity = entityComponent.GetEntity(entityId);
|
||||
if (entity == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return (EntityBase)entity.Logic;
|
||||
}
|
||||
|
||||
public static void HideEntity(this EntityComponent entityComponent, EntityBase entity)
|
||||
{
|
||||
entityComponent.HideEntity(entity.Entity);
|
||||
}
|
||||
|
||||
public static void AttachEntity(this EntityComponent entityComponent, EntityBase entityBase, int ownerId,
|
||||
string parentTransformPath = null, object userData = null)
|
||||
{
|
||||
entityComponent.AttachEntity(entityBase.Entity, ownerId, parentTransformPath, userData);
|
||||
}
|
||||
|
||||
public static void ShowPlayer(this EntityComponent entityComponent, PlayerData data)
|
||||
{
|
||||
entityComponent.ShowEntity(typeof(Player), "Player", Constant.AssetPriority.PlayerAsset, data);
|
||||
}
|
||||
|
||||
public static void ShowEnemy(this EntityComponent entityComponent, EnemyData data)
|
||||
{
|
||||
string typeName = EntityNamespace + (EnemyType)data.TypeId;
|
||||
if (!_typeDict.TryGetValue(typeName, out Type enemyType))
|
||||
{
|
||||
enemyType = Type.GetType(typeName);
|
||||
if (enemyType == null)
|
||||
{
|
||||
Log.Warning("Can not load entity type '{0}'.", typeName);
|
||||
return;
|
||||
}
|
||||
|
||||
_typeDict.Add(typeName, enemyType);
|
||||
}
|
||||
|
||||
entityComponent.ShowEntity(enemyType, "Enemy", Constant.AssetPriority.EnemyAsset, data);
|
||||
}
|
||||
|
||||
public static void ShowWeapon(this EntityComponent entityComponent, WeaponData data)
|
||||
{
|
||||
string typeName = EntityNamespace + (WeaponType)data.TypeId;
|
||||
if (!_typeDict.TryGetValue(typeName, out Type weaponType))
|
||||
{
|
||||
weaponType = Type.GetType(typeName);
|
||||
if (weaponType == null)
|
||||
{
|
||||
Log.Warning("Can not load entity type '{0}'.", typeName);
|
||||
return;
|
||||
}
|
||||
|
||||
_typeDict.Add(typeName, weaponType);
|
||||
}
|
||||
|
||||
entityComponent.ShowEntity(weaponType, "Weapon", Constant.AssetPriority.WeaponAsset, data);
|
||||
}
|
||||
|
||||
public static void ShowBullet(this EntityComponent entityComponent, BulletData data)
|
||||
{
|
||||
entityComponent.ShowEntity(typeof(Bullet), "Bullet", Constant.AssetPriority.BulletAsset, data);
|
||||
}
|
||||
|
||||
public static void ShowEffect(this EntityComponent entityComponent, EffectData data)
|
||||
{
|
||||
entityComponent.ShowEntity(typeof(Effect), "Effect", Constant.AssetPriority.EffectAsset, data);
|
||||
}
|
||||
|
||||
public static void ShowCoin(this EntityComponent entityComponent, CoinData data)
|
||||
{
|
||||
entityComponent.ShowEntity(typeof(CoinEntity), "Drop", Constant.AssetPriority.EffectAsset, data);
|
||||
}
|
||||
|
||||
public static void ShowExp(this EntityComponent entityComponent, ExpData data)
|
||||
{
|
||||
entityComponent.ShowEntity(typeof(ExpEntity), "Drop", Constant.AssetPriority.EffectAsset, data);
|
||||
}
|
||||
|
||||
private static void ShowEntity(this EntityComponent entityComponent, Type logicType, string entityGroup,
|
||||
int priority, EntityDataBase data)
|
||||
{
|
||||
if (data == null)
|
||||
{
|
||||
Log.Warning("Data is invalid.");
|
||||
return;
|
||||
}
|
||||
|
||||
DREntity drEntity = GameEntry.DataTable.GetDataTableRow<DREntity>(data.TypeId);
|
||||
if (drEntity == null)
|
||||
{
|
||||
Log.Warning("Can not load entity id '{0}' from data table.", data.TypeId.ToString());
|
||||
return;
|
||||
}
|
||||
|
||||
entityComponent.ShowEntity(data.Id, logicType, AssetUtility.GetEntityAsset(drEntity.AssetName), entityGroup,
|
||||
priority, data);
|
||||
}
|
||||
|
||||
public static int GenerateSerialId(this EntityComponent entityComponent)
|
||||
{
|
||||
return --s_SerialId;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 626632079980ad34595c3b43a062a664
|
||||
timeCreated: 1528026153
|
||||
licenseType: Pro
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,9 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 74fbdf043ed3bc141a0a0b09756bc7d2
|
||||
folderAsset: yes
|
||||
timeCreated: 1528026153
|
||||
licenseType: Pro
|
||||
DefaultImporter:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,53 @@
|
||||
//------------------------------------------------------------
|
||||
// Game Framework
|
||||
// Copyright © 2013-2021 Jiang Yin. All rights reserved.
|
||||
// Homepage: https://gameframework.cn/
|
||||
// Feedback: mailto:ellan@gameframework.cn
|
||||
//------------------------------------------------------------
|
||||
|
||||
using Definition.DataStruct;
|
||||
using Entity.EntityData;
|
||||
using StarForce;
|
||||
using UnityEngine;
|
||||
using UnityGameFramework.Runtime;
|
||||
|
||||
namespace Entity
|
||||
{
|
||||
/// <summary>
|
||||
/// 子弹类。
|
||||
/// </summary>
|
||||
public class Bullet : EntityBase
|
||||
{
|
||||
[SerializeField] private BulletData m_BulletData = null;
|
||||
|
||||
public ImpactData GetImpactData()
|
||||
{
|
||||
//TODO:子弹的 AttackStat 不该为 null
|
||||
return new ImpactData(m_BulletData.OwnerCamp, m_BulletData.Attack, null);
|
||||
}
|
||||
|
||||
protected override void OnInit(object userData)
|
||||
{
|
||||
base.OnInit(userData);
|
||||
}
|
||||
|
||||
protected override void OnShow(object userData)
|
||||
{
|
||||
base.OnShow(userData);
|
||||
|
||||
m_BulletData = userData as BulletData;
|
||||
if (m_BulletData == null)
|
||||
{
|
||||
Log.Error("Bullet data is invalid.");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnUpdate(float elapseSeconds, float realElapseSeconds)
|
||||
{
|
||||
base.OnUpdate(elapseSeconds, realElapseSeconds);
|
||||
|
||||
CachedTransform.Translate(Vector3.forward * m_BulletData.Speed * elapseSeconds, Space.World);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 822be177ff3fd674fa34da0755f1a427
|
||||
timeCreated: 1528026153
|
||||
licenseType: Pro
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,37 @@
|
||||
using Entity.EntityData;
|
||||
using UnityEngine;
|
||||
using UnityGameFramework.Runtime;
|
||||
|
||||
namespace Entity
|
||||
{
|
||||
public class CoinEntity : EntityBase
|
||||
{
|
||||
private CoinData _coinData;
|
||||
|
||||
protected override void OnShow(object userData)
|
||||
{
|
||||
base.OnShow(userData);
|
||||
|
||||
if (userData is CoinData coinData)
|
||||
{
|
||||
_coinData = coinData;
|
||||
}
|
||||
else
|
||||
{
|
||||
Log.Error("CoinEntity.OnShow() called with wrong type.");
|
||||
}
|
||||
|
||||
this.CachedTransform.localScale = new Vector3(0.3f, 0.3f, 0.3f);
|
||||
}
|
||||
|
||||
private void OnTriggerEnter(Collider other)
|
||||
{
|
||||
var player = other.GetComponent<Player>();
|
||||
if (player != null && player.Available)
|
||||
{
|
||||
player.Coin += _coinData.Value;
|
||||
GameEntry.Entity.HideEntity(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 0878ab0829c34f44a83d5e5a1eb586ea
|
||||
timeCreated: 1770292173
|
||||
@@ -0,0 +1,58 @@
|
||||
//------------------------------------------------------------
|
||||
// Game Framework
|
||||
// Copyright © 2013-2021 Jiang Yin. All rights reserved.
|
||||
// Homepage: https://gameframework.cn/
|
||||
// Feedback: mailto:ellan@gameframework.cn
|
||||
//------------------------------------------------------------
|
||||
|
||||
using Entity;
|
||||
using Entity.EntityData;
|
||||
using UnityEngine;
|
||||
using UnityGameFramework.Runtime;
|
||||
|
||||
namespace Entity
|
||||
{
|
||||
/// <summary>
|
||||
/// 特效类。
|
||||
/// </summary>
|
||||
public class Effect : EntityBase
|
||||
{
|
||||
[SerializeField]
|
||||
private EffectData m_EffectData = null;
|
||||
|
||||
private float m_ElapseSeconds = 0f;
|
||||
|
||||
#if UNITY_2017_3_OR_NEWER
|
||||
protected override void OnShow(object userData)
|
||||
#else
|
||||
protected internal override void OnShow(object userData)
|
||||
#endif
|
||||
{
|
||||
base.OnShow(userData);
|
||||
|
||||
m_EffectData = userData as EffectData;
|
||||
if (m_EffectData == null)
|
||||
{
|
||||
Log.Error("Effect data is invalid.");
|
||||
return;
|
||||
}
|
||||
|
||||
m_ElapseSeconds = 0f;
|
||||
}
|
||||
|
||||
#if UNITY_2017_3_OR_NEWER
|
||||
protected override void OnUpdate(float elapseSeconds, float realElapseSeconds)
|
||||
#else
|
||||
protected internal override void OnUpdate(float elapseSeconds, float realElapseSeconds)
|
||||
#endif
|
||||
{
|
||||
base.OnUpdate(elapseSeconds, realElapseSeconds);
|
||||
|
||||
m_ElapseSeconds += elapseSeconds;
|
||||
if (m_ElapseSeconds >= m_EffectData.KeepTime)
|
||||
{
|
||||
GameEntry.Entity.HideEntity(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c3e408851e9ea064bb8bc08fbb10b33f
|
||||
timeCreated: 1528026154
|
||||
licenseType: Pro
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 81c9b48d9ff1bce45b91ffa040b1db2a
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,12 @@
|
||||
using Definition.DataStruct;
|
||||
using Entity;
|
||||
using UnityEngine;
|
||||
|
||||
public abstract class EnemyBase : TargetableObject
|
||||
{
|
||||
protected Transform _target;
|
||||
|
||||
public abstract override ImpactData GetImpactData();
|
||||
|
||||
public virtual void SetTarget(Transform target) => _target = target;
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d33d6ac2d1874d4418780e3354e6b4e3
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,115 @@
|
||||
using Components;
|
||||
using Definition.DataStruct;
|
||||
using Entity.EntityData;
|
||||
using UnityEngine;
|
||||
using UnityGameFramework.Runtime;
|
||||
|
||||
namespace Entity
|
||||
{
|
||||
public class MeleeEnemy : EnemyBase
|
||||
{
|
||||
private MovementComponent _movementComponent;
|
||||
private float _attackRange = 1f;
|
||||
private float _attackRangeSquared;
|
||||
private EnemyData _meleeEnemyData;
|
||||
private WeaponBase _weapon;
|
||||
|
||||
protected override TargetableObjectData _targetableObjectData => _meleeEnemyData;
|
||||
|
||||
public override ImpactData GetImpactData()
|
||||
{
|
||||
return new ImpactData(_meleeEnemyData.Camp, 0);
|
||||
}
|
||||
|
||||
#region FSM
|
||||
|
||||
protected override void OnInit(object userData)
|
||||
{
|
||||
base.OnInit(userData);
|
||||
|
||||
_movementComponent = GetComponent<MovementComponent>();
|
||||
_healthComponent = GetComponent<HealthComponent>();
|
||||
}
|
||||
|
||||
protected override void OnShow(object userData)
|
||||
{
|
||||
base.OnShow(userData);
|
||||
|
||||
if (userData is EnemyData enemyData)
|
||||
{
|
||||
_meleeEnemyData = enemyData;
|
||||
_healthComponent.OnInit(enemyData.MaxHealthBase);
|
||||
_movementComponent.OnInit(_meleeEnemyData.SpeedBase, this.CachedTransform);
|
||||
_movementComponent.SetMove(true);
|
||||
_attackRangeSquared = _attackRange * _attackRange;
|
||||
this.CachedTransform.position = enemyData.Position;
|
||||
}
|
||||
else
|
||||
{
|
||||
Log.Error($"Invalid data type. Data type: {userData?.GetType()}");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
protected override void OnUpdate(float elapseSeconds, float realElapseSeconds)
|
||||
{
|
||||
base.OnUpdate(elapseSeconds, realElapseSeconds);
|
||||
|
||||
float distanceSquared = (this.CachedTransform.position - _target.position).sqrMagnitude;
|
||||
if (distanceSquared < _attackRangeSquared)
|
||||
{
|
||||
// 攻击
|
||||
_movementComponent.SetMove(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
_movementComponent.SetMove(true);
|
||||
_movementComponent.SetDirection(GetTargetDirection());
|
||||
}
|
||||
|
||||
_movementComponent.OnUpdate(elapseSeconds, realElapseSeconds);
|
||||
}
|
||||
|
||||
protected override void OnDead(EntityBase attacker)
|
||||
{
|
||||
if (Random.value < _meleeEnemyData.DropPercent)
|
||||
{
|
||||
var data = new CoinData(_meleeEnemyData.DropCoin, GameEntry.Entity.GenerateSerialId(), 10001)
|
||||
{
|
||||
Position = this.CachedTransform.position
|
||||
};
|
||||
GameEntry.Entity.ShowCoin(data);
|
||||
}
|
||||
|
||||
if (Random.value < _meleeEnemyData.DropPercent)
|
||||
{
|
||||
var data = new ExpData(_meleeEnemyData.DropExp, GameEntry.Entity.GenerateSerialId(), 10002)
|
||||
{
|
||||
Position = this.CachedTransform.position
|
||||
};
|
||||
GameEntry.Entity.ShowExp(data);
|
||||
}
|
||||
|
||||
base.OnDead(attacker);
|
||||
}
|
||||
|
||||
protected override void OnHide(bool isShutdown, object userData)
|
||||
{
|
||||
_movementComponent.OnReset();
|
||||
_healthComponent.OnReset();
|
||||
|
||||
base.OnHide(isShutdown, userData);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private Vector3 GetTargetDirection()
|
||||
{
|
||||
return new Vector3(
|
||||
_target.position.x - this.CachedTransform.position.x,
|
||||
0f,
|
||||
_target.position.z - this.CachedTransform.position.z
|
||||
).normalized;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 112f2a17ab82438484782c9a763fdee1
|
||||
timeCreated: 1768892870
|
||||
@@ -0,0 +1,87 @@
|
||||
using Components;
|
||||
using Definition.DataStruct;
|
||||
using Entity.EntityData;
|
||||
using UnityEngine;
|
||||
using UnityGameFramework.Runtime;
|
||||
|
||||
namespace Entity
|
||||
{
|
||||
public class RemoteEnemy : EnemyBase
|
||||
{
|
||||
private float _speed;
|
||||
private MovementComponent _movementComponent;
|
||||
private float _attackRange = 1f;
|
||||
private float _attackRangeSquared;
|
||||
private EnemyData _remoteEnemyData;
|
||||
|
||||
protected override TargetableObjectData _targetableObjectData => _remoteEnemyData;
|
||||
|
||||
public override ImpactData GetImpactData()
|
||||
{
|
||||
return new ImpactData(_remoteEnemyData.Camp, 0);
|
||||
}
|
||||
|
||||
protected override void OnInit(object userData)
|
||||
{
|
||||
base.OnInit(userData);
|
||||
|
||||
_movementComponent = GetComponent<MovementComponent>();
|
||||
_healthComponent = GetComponent<HealthComponent>();
|
||||
}
|
||||
|
||||
protected override void OnShow(object userData)
|
||||
{
|
||||
base.OnShow(userData);
|
||||
|
||||
if (userData is EnemyData enemyData)
|
||||
{
|
||||
_remoteEnemyData = enemyData;
|
||||
_healthComponent.OnInit(enemyData.MaxHealthBase);
|
||||
_movementComponent.OnInit(_remoteEnemyData.SpeedBase, this.CachedTransform);
|
||||
_movementComponent.SetMove(true);
|
||||
_attackRangeSquared = _attackRange * _attackRange;
|
||||
this.CachedTransform.position = enemyData.Position;
|
||||
}
|
||||
else
|
||||
{
|
||||
Log.Error($"Invalid data type. Data type: {userData?.GetType()}");
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnUpdate(float elapseSeconds, float realElapseSeconds)
|
||||
{
|
||||
base.OnUpdate(elapseSeconds, realElapseSeconds);
|
||||
|
||||
float distanceSquared = (this.CachedTransform.position - _target.position).sqrMagnitude;
|
||||
if (distanceSquared < _attackRangeSquared)
|
||||
{
|
||||
// 攻击
|
||||
_movementComponent.SetMove(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
_movementComponent.SetMove(true);
|
||||
_movementComponent.SetDirection(GetTargetDirection());
|
||||
}
|
||||
|
||||
_movementComponent.OnUpdate(elapseSeconds, realElapseSeconds);
|
||||
}
|
||||
|
||||
protected override void OnHide(bool isShutdown, object userData)
|
||||
{
|
||||
_movementComponent.OnReset();
|
||||
_healthComponent.OnReset();
|
||||
|
||||
base.OnHide(isShutdown, userData);
|
||||
}
|
||||
|
||||
private Vector3 GetTargetDirection()
|
||||
{
|
||||
return new Vector3(
|
||||
_target.position.x - this.CachedTransform.position.x,
|
||||
0f,
|
||||
_target.position.z - this.CachedTransform.position.z
|
||||
).normalized;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b90e05d1e7a5475bb928b2445e113767
|
||||
timeCreated: 1770209676
|
||||
@@ -0,0 +1,82 @@
|
||||
//------------------------------------------------------------
|
||||
// Game Framework
|
||||
// Copyright © 2013-2021 Jiang Yin. All rights reserved.
|
||||
// Homepage: https://gameframework.cn/
|
||||
// Feedback: mailto:ellan@gameframework.cn
|
||||
//------------------------------------------------------------
|
||||
|
||||
using Entity.EntityData;
|
||||
using GameFramework;
|
||||
using UnityEngine;
|
||||
using UnityGameFramework.Runtime;
|
||||
|
||||
namespace Entity
|
||||
{
|
||||
public abstract class EntityBase : EntityLogic
|
||||
{
|
||||
[SerializeField] private EntityDataBase _entityData = null;
|
||||
|
||||
public int Id => Entity.Id;
|
||||
|
||||
public Animation CachedAnimation { get; private set; }
|
||||
|
||||
protected override void OnInit(object userData)
|
||||
{
|
||||
base.OnInit(userData);
|
||||
CachedAnimation = GetComponent<Animation>();
|
||||
}
|
||||
|
||||
protected override void OnRecycle()
|
||||
{
|
||||
base.OnRecycle();
|
||||
}
|
||||
|
||||
protected override void OnShow(object userData)
|
||||
{
|
||||
base.OnShow(userData);
|
||||
|
||||
_entityData = userData as EntityDataBase;
|
||||
if (_entityData == null)
|
||||
{
|
||||
Log.Error("Entity data is invalid.");
|
||||
return;
|
||||
}
|
||||
|
||||
Name = Utility.Text.Format("[Entity {0}]", Id);
|
||||
CachedTransform.localPosition = _entityData.Position;
|
||||
CachedTransform.localRotation = _entityData.Rotation;
|
||||
CachedTransform.localScale = Vector3.one;
|
||||
}
|
||||
|
||||
|
||||
protected override void OnHide(bool isShutdown, object userData)
|
||||
{
|
||||
base.OnHide(isShutdown, userData);
|
||||
}
|
||||
|
||||
protected override void OnAttached(EntityLogic childEntity, Transform parentTransform, object userData)
|
||||
{
|
||||
base.OnAttached(childEntity, parentTransform, userData);
|
||||
}
|
||||
|
||||
protected override void OnDetached(EntityLogic childEntity, object userData)
|
||||
{
|
||||
base.OnDetached(childEntity, userData);
|
||||
}
|
||||
|
||||
protected override void OnAttachTo(EntityLogic parentEntity, Transform parentTransform, object userData)
|
||||
{
|
||||
base.OnAttachTo(parentEntity, parentTransform, userData);
|
||||
}
|
||||
|
||||
protected override void OnDetachFrom(EntityLogic parentEntity, object userData)
|
||||
{
|
||||
base.OnDetachFrom(parentEntity, userData);
|
||||
}
|
||||
|
||||
protected override void OnUpdate(float elapseSeconds, float realElapseSeconds)
|
||||
{
|
||||
base.OnUpdate(elapseSeconds, realElapseSeconds);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 878fbbe82b4bde944812bcb7c964cff8
|
||||
timeCreated: 1528026154
|
||||
licenseType: Pro
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,36 @@
|
||||
using Entity.EntityData;
|
||||
using UnityEngine;
|
||||
using UnityGameFramework.Runtime;
|
||||
|
||||
namespace Entity
|
||||
{
|
||||
public class ExpEntity:EntityBase
|
||||
{
|
||||
private ExpData _expData;
|
||||
|
||||
protected override void OnShow(object userData)
|
||||
{
|
||||
base.OnShow(userData);
|
||||
|
||||
if (userData is ExpData expData)
|
||||
{
|
||||
_expData = expData;
|
||||
}
|
||||
else
|
||||
{
|
||||
Log.Error("expEntity.OnShow() called with wrong type.");
|
||||
}
|
||||
this.CachedTransform.localScale = new Vector3(0.3f, 0.3f, 0.3f);
|
||||
}
|
||||
|
||||
private void OnTriggerEnter(Collider other)
|
||||
{
|
||||
var player = other.GetComponent<Player>();
|
||||
if (player != null && player.Available)
|
||||
{
|
||||
player.Exp += _expData.Value;
|
||||
GameEntry.Entity.HideEntity(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ec4ae4b0a327442a88463eafd59c5b6e
|
||||
timeCreated: 1770293001
|
||||
@@ -0,0 +1,191 @@
|
||||
using Components;
|
||||
using CustomEvent;
|
||||
using DataTable;
|
||||
using Definition.DataStruct;
|
||||
using Entity.EntityData;
|
||||
using GameFramework.Event;
|
||||
using UnityGameFramework.Runtime;
|
||||
|
||||
namespace Entity
|
||||
{
|
||||
public class Player : TargetableObject
|
||||
{
|
||||
protected override TargetableObjectData _targetableObjectData => _playerData;
|
||||
|
||||
private InputComponent _inputComponent;
|
||||
private MovementComponent _movementComponent;
|
||||
private StatComponent _statComponent;
|
||||
private BackpackComponent _backpackComponent;
|
||||
private PlayerData _playerData;
|
||||
|
||||
/// <summary>
|
||||
/// 当前金币。
|
||||
/// </summary>
|
||||
private int _coin;
|
||||
|
||||
/// <summary>
|
||||
/// 当前经验。
|
||||
/// </summary>
|
||||
private int _exp;
|
||||
|
||||
/// <summary>
|
||||
/// 每级所需的经验。
|
||||
/// tip: _expRequires[1] 表示 Lv 0 -> Lv 1 需要的经验
|
||||
/// </summary>
|
||||
private int[] _expRequires;
|
||||
|
||||
/// <summary>
|
||||
/// 当前的角色等级。
|
||||
/// </summary>
|
||||
private int _currentLevel;
|
||||
|
||||
/// <summary>
|
||||
/// 玩家是否启用。
|
||||
/// </summary>
|
||||
private bool _enable;
|
||||
|
||||
public int Coin
|
||||
{
|
||||
get => _coin;
|
||||
set
|
||||
{
|
||||
GameEntry.Event.Fire(this, PlayerCoinChangeEventArgs.Create(value - _coin, value));
|
||||
_coin = value;
|
||||
}
|
||||
}
|
||||
|
||||
public int Exp
|
||||
{
|
||||
get => _exp;
|
||||
set
|
||||
{
|
||||
if (value >= _expRequires[_currentLevel + 1])
|
||||
{
|
||||
value -= _expRequires[_currentLevel + 1];
|
||||
_currentLevel++;
|
||||
}
|
||||
|
||||
GameEntry.Event.Fire(this, PlayerExpChangeEventArgs.Create(value, _expRequires[_currentLevel + 1]));
|
||||
_exp = value;
|
||||
}
|
||||
}
|
||||
|
||||
public bool Enable
|
||||
{
|
||||
get => _enable;
|
||||
set
|
||||
{
|
||||
if (value == _enable) return;
|
||||
_movementComponent.SetMove(value);
|
||||
_backpackComponent.SetWeaponState(value);
|
||||
_inputComponent.SetListening(value);
|
||||
}
|
||||
}
|
||||
|
||||
public void InitRole(DRRole role)
|
||||
{
|
||||
// MovementComponent
|
||||
_movementComponent.OnInit(role.Speed, this.CachedTransform, _statComponent);
|
||||
_movementComponent.SetMove(true);
|
||||
|
||||
// HealthComponent
|
||||
_healthComponent.OnInit(role.MaxHealth, _statComponent);
|
||||
|
||||
// BackpackComponent
|
||||
Coin = role.Coin;
|
||||
_backpackComponent.OnInit(this, role.WeaponCapacity);
|
||||
GameEntry.Entity.ShowWeapon(new WeaponKnifeData(GameEntry.Entity.GenerateSerialId(), 201,
|
||||
this.Id, _playerData.Camp));
|
||||
|
||||
// StatComponent
|
||||
foreach (var modifier in role.InitialProperties)
|
||||
{
|
||||
_statComponent.AddModifier(modifier);
|
||||
}
|
||||
|
||||
_expRequires = role.ExpRequires;
|
||||
|
||||
// Fire Events
|
||||
GameEntry.Event.Fire(this,
|
||||
PlayerHealthChangeEventArgs.Create(0, _healthComponent.CurrentHealth, _healthComponent.MaxHealth));
|
||||
|
||||
GameEntry.Event.Fire(this, PlayerExpChangeEventArgs.Create(0, 100));
|
||||
|
||||
GameEntry.Event.Fire(this,
|
||||
PlayerCoinChangeEventArgs.Create(Coin, Coin));
|
||||
}
|
||||
|
||||
#region FSM
|
||||
|
||||
public override ImpactData GetImpactData()
|
||||
{
|
||||
return new ImpactData(_playerData.Camp, 0, null, _healthComponent.DefenseStat, _healthComponent.DodgeStat);
|
||||
}
|
||||
|
||||
protected override void OnInit(object userData)
|
||||
{
|
||||
base.OnInit(userData);
|
||||
|
||||
_inputComponent = GetComponent<InputComponent>();
|
||||
_movementComponent = GetComponent<MovementComponent>();
|
||||
_statComponent = GetComponent<StatComponent>();
|
||||
_healthComponent = GetComponent<HealthComponent>();
|
||||
_backpackComponent = GetComponent<BackpackComponent>();
|
||||
}
|
||||
|
||||
protected override void OnShow(object userData)
|
||||
{
|
||||
base.OnShow(userData);
|
||||
|
||||
GameEntry.Event.Subscribe(ShowEntitySuccessEventArgs.EventId, ShowEntitySuccess);
|
||||
|
||||
_statComponent.OnInit();
|
||||
|
||||
if (userData is PlayerData playerData)
|
||||
{
|
||||
_playerData = playerData;
|
||||
}
|
||||
|
||||
_inputComponent.OnInit();
|
||||
_inputComponent.SetListening(true);
|
||||
|
||||
_currentLevel = 0;
|
||||
}
|
||||
|
||||
protected override void OnUpdate(float elapseSeconds, float realElapseSeconds)
|
||||
{
|
||||
base.OnUpdate(elapseSeconds, realElapseSeconds);
|
||||
|
||||
_inputComponent.OnUpdate(elapseSeconds, realElapseSeconds);
|
||||
|
||||
_movementComponent.SetDirection(_inputComponent.Direction);
|
||||
_movementComponent.OnUpdate(elapseSeconds, realElapseSeconds);
|
||||
}
|
||||
|
||||
protected override void OnHide(bool isShutdown, object userData)
|
||||
{
|
||||
_inputComponent.OnReset();
|
||||
_movementComponent.OnReset();
|
||||
_healthComponent.OnReset();
|
||||
_statComponent.OnReset();
|
||||
_backpackComponent.OnReset();
|
||||
|
||||
base.OnHide(isShutdown, userData);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Event Handlers
|
||||
|
||||
private void ShowEntitySuccess(object sender, GameEventArgs e)
|
||||
{
|
||||
if (!(e is ShowEntitySuccessEventArgs args)) return;
|
||||
if (args.Entity.Logic is WeaponBase weapon)
|
||||
{
|
||||
_backpackComponent.AttachWeapon(weapon);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3979cb10abff0944aad09de04ec7813a
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,83 @@
|
||||
//------------------------------------------------------------
|
||||
// Game Framework
|
||||
// Copyright © 2013-2021 Jiang Yin. All rights reserved.
|
||||
// Homepage: https://gameframework.cn/
|
||||
// Feedback: mailto:ellan@gameframework.cn
|
||||
//------------------------------------------------------------
|
||||
|
||||
using Components;
|
||||
using Definition;
|
||||
using Definition.DataStruct;
|
||||
using Entity.EntityData;
|
||||
using StarForce;
|
||||
using UnityEngine;
|
||||
using UnityGameFramework.Runtime;
|
||||
|
||||
namespace Entity
|
||||
{
|
||||
/// <summary>
|
||||
/// 可作为目标的实体类。
|
||||
/// </summary>
|
||||
public abstract class TargetableObject : EntityBase
|
||||
{
|
||||
protected abstract TargetableObjectData _targetableObjectData { get; }
|
||||
|
||||
public bool IsDead => _healthComponent.CurrentHealth <= 0;
|
||||
|
||||
protected HealthComponent _healthComponent;
|
||||
|
||||
public abstract ImpactData GetImpactData();
|
||||
|
||||
public void ApplyDamage(EntityBase attacker, int damageHP)
|
||||
{
|
||||
float fromHPRatio = _healthComponent.HealthRatio;
|
||||
_healthComponent.TakeDamage(damageHP);
|
||||
float toHPRatio = _healthComponent.HealthRatio;
|
||||
if (fromHPRatio > toHPRatio)
|
||||
{
|
||||
GameEntry.HPBar.ShowHPBar(this, fromHPRatio, toHPRatio);
|
||||
}
|
||||
|
||||
if (_healthComponent.CurrentHealth <= 0)
|
||||
{
|
||||
OnDead(attacker);
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnInit(object userData)
|
||||
{
|
||||
base.OnInit(userData);
|
||||
|
||||
_healthComponent = GetComponent<HealthComponent>();
|
||||
}
|
||||
|
||||
protected override void OnShow(object userData)
|
||||
{
|
||||
base.OnShow(userData);
|
||||
}
|
||||
|
||||
protected virtual void OnDead(EntityBase attacker)
|
||||
{
|
||||
GameEntry.Entity.HideEntity(this);
|
||||
}
|
||||
|
||||
private void OnTriggerEnter(Collider other)
|
||||
{
|
||||
EntityBase entity = other.gameObject.GetComponent<EntityBase>();
|
||||
if (entity == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (entity is TargetableObject && entity.Id < Id)
|
||||
{
|
||||
// 碰撞事件由 Id 大的一方处理
|
||||
// 在这里规定所有的 Enemy 的 Id 均大于 0
|
||||
// 而其他的 Entity (Player, Weapon, Bullet) 的 Id 均小于 0
|
||||
return;
|
||||
}
|
||||
|
||||
AIUtility.PerformCollision(this, entity);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 4a1fd351b05d994459122be1a39507b1
|
||||
timeCreated: 1528026154
|
||||
licenseType: Pro
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6b5f40df44fe005498fc03555871b8ad
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,83 @@
|
||||
using System;
|
||||
using Definition.DataStruct;
|
||||
using Entity.EntityData;
|
||||
using GameFramework;
|
||||
using UnityEngine;
|
||||
using UnityGameFramework.Runtime;
|
||||
|
||||
namespace Entity
|
||||
{
|
||||
public enum WeaponStateType
|
||||
{
|
||||
Disabled,
|
||||
Check,
|
||||
Attack,
|
||||
Transition,
|
||||
Idle,
|
||||
Check_OutRange,
|
||||
Check_InRange,
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 武器类。
|
||||
/// </summary>
|
||||
public abstract class WeaponBase : EntityBase
|
||||
{
|
||||
protected const string AttachPoint = "Weapon Point";
|
||||
protected bool _isAttacking = false;
|
||||
protected bool _isEnabled = false;
|
||||
public WeaponData WeaponData;
|
||||
public bool IsAttacking => _isAttacking;
|
||||
protected WeaponStateBase _currentState;
|
||||
|
||||
#region FSM
|
||||
|
||||
protected override void OnInit(object userData)
|
||||
{
|
||||
base.OnInit(userData);
|
||||
}
|
||||
|
||||
//protected abstract void OnShow(object userData);
|
||||
// {
|
||||
// base.OnShow(userData);
|
||||
//
|
||||
// _weaponData = userData as WeaponData;
|
||||
// if (_weaponData == null)
|
||||
// {
|
||||
// Log.Error("Weapon data is invalid.");
|
||||
// return;
|
||||
// }
|
||||
// }
|
||||
|
||||
protected override void OnAttachTo(EntityLogic parentEntity, Transform parentTransform, object userData)
|
||||
{
|
||||
base.OnAttachTo(parentEntity, parentTransform, userData);
|
||||
|
||||
Name = Utility.Text.Format("Weapon of {0}", parentEntity.Name);
|
||||
CachedTransform.localPosition = Vector3.zero;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
public abstract ImpactData GetImpactData();
|
||||
protected abstract void Attack();
|
||||
protected abstract void Check();
|
||||
protected abstract void TransitionTo(WeaponStateType newState);
|
||||
|
||||
public void SetEnabled(bool value)
|
||||
{
|
||||
this._isEnabled = value;
|
||||
TransitionTo(WeaponStateType.Idle);
|
||||
}
|
||||
}
|
||||
|
||||
public abstract class WeaponStateBase
|
||||
{
|
||||
public abstract WeaponStateType State { get; }
|
||||
public abstract void OnInit(WeaponBase weapon);
|
||||
public abstract void OnEnter();
|
||||
public abstract void OnUpdate(float elapseSeconds, float realElapseSeconds);
|
||||
public abstract void OnLeave();
|
||||
public override string ToString() => State.ToString();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: fc18f1a1232bb9644be1191168741922
|
||||
timeCreated: 1528026154
|
||||
licenseType: Pro
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,332 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Components;
|
||||
using CustomComponent;
|
||||
using Definition.DataStruct;
|
||||
using Definition.Enum;
|
||||
using DG.Tweening;
|
||||
using Entity.EntityData;
|
||||
using StarForce;
|
||||
using UnityEngine;
|
||||
using UnityGameFramework.Runtime;
|
||||
|
||||
namespace Entity
|
||||
{
|
||||
public class WeaponKnife : WeaponBase
|
||||
{
|
||||
private WeaponKnifeData _weaponData;
|
||||
private float _currAttackTimer = 0f;
|
||||
private EnemyManagerComponent _enemy;
|
||||
private EntityBase _target;
|
||||
|
||||
private float _sqrRange;
|
||||
|
||||
private Collider _collider;
|
||||
private Rigidbody _rigidbody;
|
||||
private Quaternion _cachedRotation;
|
||||
[SerializeField] private float _rotateSpeed = 2f;
|
||||
|
||||
private Dictionary<WeaponStateType, WeaponStateBase> _weaponStates;
|
||||
|
||||
private StatProperty _attackStat = new();
|
||||
private Action<StatModifier, bool> _attackStatCallback;
|
||||
|
||||
[SerializeField] private float attackDuration = 0.15f; // 戳刺持续时间
|
||||
[SerializeField] private float returnDuration = 0.2f; // 回归持续时间
|
||||
|
||||
public override ImpactData GetImpactData()
|
||||
{
|
||||
return new ImpactData(_weaponData.OwnerCamp, _weaponData.Attack, _attackStat);
|
||||
}
|
||||
|
||||
private void InitStates()
|
||||
{
|
||||
_weaponStates = new Dictionary<WeaponStateType, WeaponStateBase>
|
||||
{
|
||||
{ WeaponStateType.Idle, new IdleState() },
|
||||
{ WeaponStateType.Check_InRange, new CheckInRangeState() },
|
||||
{ WeaponStateType.Check_OutRange, new CheckOutRangeState() },
|
||||
{ WeaponStateType.Attack, new AttackState() }
|
||||
};
|
||||
foreach (var state in _weaponStates.Values)
|
||||
{
|
||||
state.OnInit(this);
|
||||
}
|
||||
}
|
||||
|
||||
#region FSM Methods
|
||||
|
||||
protected override void Attack()
|
||||
{
|
||||
Vector3 targetPos = CachedTransform.position + CachedTransform.forward * _weaponData.AttackRange;
|
||||
_isAttacking = true;
|
||||
_collider.enabled = true;
|
||||
_rigidbody.detectCollisions = true;
|
||||
Transform parentTransform = CachedTransform.parent;
|
||||
CachedTransform.SetParent(null);
|
||||
|
||||
var sequence = DOTween.Sequence();
|
||||
sequence.Append(CachedTransform.DOMove(targetPos, attackDuration).SetEase(Ease.OutQuad));
|
||||
sequence.AppendCallback(() =>
|
||||
{
|
||||
_collider.enabled = false;
|
||||
_rigidbody.detectCollisions = false;
|
||||
CachedTransform.SetParent(parentTransform);
|
||||
});
|
||||
sequence.Append(CachedTransform.DOLocalMove(Vector3.zero, returnDuration / 2f).SetEase(Ease.InQuad));
|
||||
sequence.AppendCallback(() => { _isAttacking = false; });
|
||||
}
|
||||
|
||||
protected override void Check()
|
||||
{
|
||||
_target = null;
|
||||
float minSqrMagnitude = float.MaxValue;
|
||||
|
||||
var enemies = _enemy.Enemies;
|
||||
foreach (var enemy in enemies)
|
||||
{
|
||||
if (enemy == null || !enemy.Available) continue;
|
||||
|
||||
float sqrMagnitude = AIUtility.GetSqrMagnitude(this, enemy);
|
||||
|
||||
if (minSqrMagnitude < sqrMagnitude) continue;
|
||||
|
||||
_target = enemy;
|
||||
minSqrMagnitude = sqrMagnitude;
|
||||
}
|
||||
}
|
||||
|
||||
private void RotateToTarget(float elapseSeconds)
|
||||
{
|
||||
if (_target == null || !_target.Available) return;
|
||||
|
||||
Vector3 directionToTarget = (_target.CachedTransform.position - transform.position).normalized;
|
||||
Quaternion targetRotation = Quaternion.LookRotation(directionToTarget, Vector3.up);
|
||||
|
||||
var quaternion = Quaternion.Slerp(CachedTransform.rotation, targetRotation, _rotateSpeed * elapseSeconds);
|
||||
CachedTransform.rotation = quaternion;
|
||||
}
|
||||
|
||||
private void RotateToOrigin(float elapseSeconds)
|
||||
{
|
||||
var quaternion = Quaternion.Slerp(CachedTransform.rotation, _cachedRotation, _rotateSpeed * elapseSeconds);
|
||||
CachedTransform.rotation = quaternion;
|
||||
}
|
||||
|
||||
protected override void TransitionTo(WeaponStateType state)
|
||||
{
|
||||
_currentState?.OnLeave();
|
||||
_currentState = _weaponStates[state];
|
||||
_currentState.OnEnter();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region FSM
|
||||
|
||||
protected override void OnShow(object userData)
|
||||
{
|
||||
base.OnShow(userData);
|
||||
|
||||
_weaponData = userData as WeaponKnifeData;
|
||||
if (_weaponData == null)
|
||||
{
|
||||
Log.Error("WeaponKnife data is invalid.");
|
||||
return;
|
||||
}
|
||||
|
||||
_collider = GetComponent<Collider>();
|
||||
_rigidbody = GetComponent<Rigidbody>();
|
||||
_currAttackTimer = 0;
|
||||
_enemy = GameEntry.EnemyManager;
|
||||
_sqrRange = _weaponData.AttackRange * _weaponData.AttackRange;
|
||||
_cachedRotation = transform.rotation;
|
||||
_collider.enabled = false;
|
||||
_rigidbody.detectCollisions = false;
|
||||
|
||||
if (_weaponData.OwnerCamp == CampType.Player)
|
||||
this.gameObject.layer = LayerMask.NameToLayer("PlayerWeapon");
|
||||
if (_weaponData.OwnerCamp == CampType.Enemy)
|
||||
this.gameObject.layer = LayerMask.NameToLayer("EnemyWeapon");
|
||||
|
||||
InitStates();
|
||||
TransitionTo(WeaponStateType.Idle);
|
||||
}
|
||||
|
||||
protected override void OnAttachTo(EntityLogic parentEntity, Transform parentTransform, object userData)
|
||||
{
|
||||
base.OnAttachTo(parentEntity, parentTransform, userData);
|
||||
|
||||
if (parentEntity is Player player)
|
||||
{
|
||||
var statComponent = player.GetComponent<StatComponent>();
|
||||
if (statComponent != null)
|
||||
{
|
||||
this._attackStat = statComponent.GetStat(StatType.Attack);
|
||||
this._attackStatCallback = (modifier, b) => statComponent.UpdateStat(_attackStat, modifier, b);
|
||||
statComponent.Subscribe(StatType.Attack, this._attackStatCallback);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnUpdate(float elapseSeconds, float realElapseSeconds)
|
||||
{
|
||||
base.OnUpdate(elapseSeconds, realElapseSeconds);
|
||||
|
||||
if (!_isEnabled) return;
|
||||
|
||||
Log.Debug($"current state: {_currentState}");
|
||||
_currentState?.OnUpdate(elapseSeconds, realElapseSeconds);
|
||||
}
|
||||
|
||||
protected override void OnDetachFrom(EntityLogic parentEntity, object userData)
|
||||
{
|
||||
base.OnDetachFrom(parentEntity, userData);
|
||||
|
||||
if (parentEntity is Player player)
|
||||
{
|
||||
var statComponent = player.GetComponent<StatComponent>();
|
||||
if (statComponent != null)
|
||||
{
|
||||
statComponent.Unsubscribe(StatType.Attack, this._attackStatCallback);
|
||||
}
|
||||
}
|
||||
|
||||
this._attackStat = null;
|
||||
this._attackStatCallback = null;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private class IdleState : WeaponStateBase
|
||||
{
|
||||
private WeaponKnife _weapon;
|
||||
|
||||
public override WeaponStateType State => WeaponStateType.Idle;
|
||||
|
||||
public override void OnInit(WeaponBase weapon) => _weapon = weapon as WeaponKnife;
|
||||
|
||||
public override void OnEnter()
|
||||
{
|
||||
}
|
||||
|
||||
public override void OnUpdate(float elapseSeconds, float realElapseSeconds)
|
||||
{
|
||||
_weapon.Check();
|
||||
_weapon.RotateToOrigin(elapseSeconds);
|
||||
if (_weapon._target != null && _weapon._target.Available)
|
||||
{
|
||||
_weapon.TransitionTo(WeaponStateType.Check_OutRange);
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnLeave()
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
private class CheckOutRangeState : WeaponStateBase
|
||||
{
|
||||
private WeaponKnife _weapon;
|
||||
|
||||
public override WeaponStateType State => WeaponStateType.Check_OutRange;
|
||||
|
||||
public override void OnInit(WeaponBase weapon) => _weapon = weapon as WeaponKnife;
|
||||
|
||||
public override void OnEnter()
|
||||
{
|
||||
}
|
||||
|
||||
public override void OnUpdate(float elapseSeconds, float realElapseSeconds)
|
||||
{
|
||||
_weapon.Check();
|
||||
_weapon.RotateToTarget(elapseSeconds);
|
||||
|
||||
if (_weapon._target == null || !_weapon._target.Available)
|
||||
{
|
||||
_weapon.TransitionTo(WeaponStateType.Idle);
|
||||
return;
|
||||
}
|
||||
|
||||
if (AIUtility.GetSqrMagnitude(_weapon._target, _weapon) < _weapon._sqrRange)
|
||||
{
|
||||
_weapon.TransitionTo(WeaponStateType.Check_InRange);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnLeave()
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
private class CheckInRangeState : WeaponStateBase
|
||||
{
|
||||
private WeaponKnife _weapon;
|
||||
|
||||
public override WeaponStateType State => WeaponStateType.Check_InRange;
|
||||
|
||||
public override void OnInit(WeaponBase weapon) => _weapon = weapon as WeaponKnife;
|
||||
|
||||
public override void OnEnter()
|
||||
{
|
||||
}
|
||||
|
||||
public override void OnUpdate(float elapseSeconds, float realElapseSeconds)
|
||||
{
|
||||
_weapon.Check();
|
||||
_weapon.RotateToTarget(elapseSeconds);
|
||||
_weapon._currAttackTimer += elapseSeconds;
|
||||
|
||||
if (_weapon._target == null || !_weapon._target.Available)
|
||||
{
|
||||
_weapon.TransitionTo(WeaponStateType.Idle);
|
||||
return;
|
||||
}
|
||||
|
||||
if (AIUtility.GetSqrMagnitude(_weapon._target, _weapon) >= _weapon._sqrRange)
|
||||
{
|
||||
_weapon.TransitionTo(WeaponStateType.Check_OutRange);
|
||||
return;
|
||||
}
|
||||
|
||||
if (_weapon._currAttackTimer >= _weapon._weaponData.Cooldown)
|
||||
{
|
||||
_weapon.TransitionTo(WeaponStateType.Attack);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnLeave()
|
||||
{
|
||||
_weapon._currAttackTimer = 0;
|
||||
}
|
||||
}
|
||||
|
||||
private class AttackState : WeaponStateBase
|
||||
{
|
||||
private WeaponKnife _weapon;
|
||||
|
||||
public override WeaponStateType State => WeaponStateType.Attack;
|
||||
|
||||
public override void OnInit(WeaponBase weapon) => _weapon = weapon as WeaponKnife;
|
||||
|
||||
public override void OnEnter()
|
||||
{
|
||||
_weapon.Attack();
|
||||
}
|
||||
|
||||
public override void OnUpdate(float elapseSeconds, float realElapseSeconds)
|
||||
{
|
||||
if (!_weapon._isAttacking)
|
||||
{
|
||||
_weapon.TransitionTo(WeaponStateType.Check_InRange);
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnLeave()
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: bbf2e0cccf970934e82f8006d5be7846
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Reference in New Issue
Block a user