我一直在关注多个来源,在 Unity Engine 中创建自己的自定义 StateMachine,没有任何子状态。我已成功创建了一个 StateMachine,它可以处理所有基本、简单的要求...
我一直在关注多个来源,以便在 Unity Engine 中创建自己的自定义 StateMachine,无需任何子状态。我成功地创建了一个 StateMachine,它可以处理视频游戏中角色的所有基本、简单的要求,例如行走、奔跑、蹲伏、躲避、转身以及单个基本的近战攻击组合。
我的目标是:使用这个 CharacterStateMachine 作为基础,创建一个敌人或各种玩家角色,如法师、巫师、坦克、弓箭手等。我还不知道如何让这个角色/职业能够在不改变职业的情况下在多个武器组之间切换?我一直在想我应该尝试在这里使用多态性和继承来与这个基类分道扬镳。
我还想使用可编写脚本的对象来保持事物清洁,并存储不同类别/敌人的伤害数字、健康值等,但这是另一篇文章的问题。
我将附上我 当前的状态和状态机, 以便从基本视觉上了解普通玩家/NPC 所共有的状态以及我有多少种状态。
每次都复制粘贴这些状态或状态机,或者用不同的名称重写每个状态脚本听起来既不高效也不合逻辑,所以我恢复到了之前的提交。我能想到的唯一方法是从 CharacterStateMachine(我的 StateMachine 的名称)派生并覆盖一些方法,如 Attack(播放远程攻击动画并造成不同的伤害数字而不是近战攻击伤害),但我不确定具体如何做到这一点。
我没有取得进一步的进展,当我尝试根据自己的需求进行研究时,我找不到可以遵循的具体解决方案。所以我来了。
感谢您的时间和意见!
因此,我正在开发一个包含大量动态雾对象的项目,我想尝试使用 DOTS,基本上它是一大堆小精灵,当玩家靠近时它们会缩小。我得到了所有...
我正在做一个包含大量动态雾对象的项目,我想尝试使用 DOTS,基本上它是一大堆小精灵,当玩家靠近时它们会缩小。我让所有工作都正常进行,现在我需要用玩家的位置更新对象。
我尝试直接传递玩家变换,但没有成功,所以我决定传递一个 vector2。但是我无法在创作脚本甚至 debug.log 中更新这个 vector2,我认为这是因为实体位于子场景中,或者因为它是一个实体,现在我正在寻找解决方法。
FogAuthoring.cs
using System.Collections;
using System.Collections.Generic;
using Unity.Entities;
using Unity.Mathematics;
using UnityEngine;
public class FogAuthoring : MonoBehaviour
{
public float LerpSpeed;
public float TargetScale;
public float2 PlayerPosition;
private Transform _player;
private void Start()
{
_player = GameObject.FindWithTag("Player").transform;
Debug.Log("A");
}
private void Update()
{
PlayerPosition = new float2(_player.position.x, _player.position.y);
Debug.Log("B");
}
private class Baker : Baker<FogAuthoring>
{
public override void Bake(FogAuthoring authoring)
{
Entity entity = GetEntity(TransformUsageFlags.Dynamic);
AddComponent(entity, new FogData
{
LerpSpeed = authoring.LerpSpeed,
TargetScale = authoring.TargetScale,
PlayerPosition = authoring.PlayerPosition
});
}
}
}
public struct FogData : IComponentData
{
public float LerpSpeed;
public float TargetScale;
public float2 PlayerPosition;
}
FogControllerDOTS.cs
using System.Collections
using System.Collections.Generic;
using UnityEngine;
using Unity.Burst;
using Unity.Entities;
using Unity.Transforms;
using Unity.Jobs;
public partial struct FogControllerDOTS : ISystem
{
public const float distThreshold = 5;
public void OnCreate(ref SystemState state)
{
state.RequireForUpdate<FogData>();
}
[BurstCompile]
public void OnUpdate(ref SystemState state)
{
/*
foreach ((RefRW<LocalTransform> localTransform, RefRO<FogData> fogData) in SystemAPI.Query<RefRW<LocalTransform>, RefRO<FogData>>())
{
float currentScale = localTransform.ValueRO.Scale;
float targetScale;
if (Vector2.Distance(new Vector2(localTransform.ValueRO.Position.x, localTransform.ValueRO.Position.y), fogData.ValueRO.PlayerPosition) <= distThreshold)
targetScale = Mathf.Lerp(currentScale, 0, fogData.ValueRO.LerpSpeed * SystemAPI.Time.DeltaTime);
else
targetScale = Mathf.Lerp(currentScale, fogData.ValueRO.TargetScale, fogData.ValueRO.LerpSpeed * SystemAPI.Time.DeltaTime);
localTransform.ValueRW = localTransform.ValueRO.WithScale(targetScale);
}*/
FogParticleJob fogParticleJob = new FogParticleJob
{
deltaTime = SystemAPI.Time.DeltaTime
};
fogParticleJob.ScheduleParallel();
}
[BurstCompile]
public partial struct FogParticleJob : IJobEntity
{
public float deltaTime;
public void Execute(ref LocalTransform localTransform, in FogData fogData)
{
float currentScale = localTransform.Scale;
float targetScale;
if (Vector2.Distance(new Vector2(localTransform.Position.x, localTransform.Position.y), fogData.PlayerPosition) <= distThreshold)
targetScale = Mathf.Lerp(currentScale, 0, fogData.LerpSpeed * deltaTime);
else
targetScale = Mathf.Lerp(currentScale, fogData.TargetScale, fogData.LerpSpeed * deltaTime);
localTransform = localTransform.WithScale(targetScale);
}
}
}