该项目的目的是同时测试和演示来自 Unity DOTS 技术堆栈的多个新包。
您最多选择25个主题 主题必须以中文或者字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符
 
 
 
 

229 行
6.9 KiB

using System;
using UnityEngine;
using Unity.Entities;
using UnityEngine.Profiling;
using System.Collections.Generic;
using Unity.Collections;
using Unity.Jobs;
[DisallowMultipleComponent]
public class NamePlateOwner : MonoBehaviour
{
public struct State : ISystemStateComponentData
{
public int namePlateId;
}
public NamePlate namePlatePrefab;
public Transform namePlateTransform;
[NonSerialized] public bool visible = true;
[NonSerialized] public string text;
[NonSerialized] public int team;
[NonSerialized] public float health;
// NamePlate not blitable, so we register in array and store index
static List<NamePlate> m_NamePlateArray = new List<NamePlate>(32);
public static NamePlate GetNamePlate(int id)
{
return m_NamePlateArray[id];
}
public static int RegisterNamePlate(NamePlate namePlate)
{
for (int i = 0; i < m_NamePlateArray.Count; i++)
{
if (m_NamePlateArray[i] == null)
{
m_NamePlateArray[i] = namePlate;
return i;
}
}
m_NamePlateArray.Add(namePlate);
return m_NamePlateArray.Count - 1;
}
public static void UnregisterNamePlate(int id)
{
m_NamePlateArray[id] = null;
}
}
[UpdateInGroup(typeof(ClientLateUpdateGroup))]
[UpdateBefore(typeof(UpdateNamePlates))]
[DisableAutoCreation]
[AlwaysSynchronizeSystem]
public class HandleNamePlateSpawn : JobComponentSystem
{
protected override JobHandle OnUpdate(JobHandle inputDeps)
{
var PostUpdateCommands = new EntityCommandBuffer(Allocator.TempJob);
Entities.WithNone<NamePlateOwner.State>()
.WithNativeDisableContainerSafetyRestriction(PostUpdateCommands)
.WithoutBurst() // Instantiates GameObjects
.ForEach((Entity entity, NamePlateOwner namePlateOwner) =>
{
var namePlate = GameObject.Instantiate(namePlateOwner.namePlatePrefab);
var id = NamePlateOwner.RegisterNamePlate(namePlate);
var state = new NamePlateOwner.State
{
namePlateId = id,
};
PostUpdateCommands.AddComponent(entity,state);
}).Run();
PostUpdateCommands.Playback(EntityManager);
PostUpdateCommands.Dispose();
return default;
}
}
[UpdateInGroup(typeof(ClientLateUpdateGroup))]
[UpdateBefore(typeof(UpdateNamePlates))]
[DisableAutoCreation]
[AlwaysSynchronizeSystem]
public class HandleNamePlateDespawn : JobComponentSystem
{
protected override JobHandle OnUpdate(JobHandle inputDeps)
{
var PostUpdateCommands = new EntityCommandBuffer(Allocator.TempJob);
Entities.WithNone<NamePlateOwner>()
.WithNativeDisableContainerSafetyRestriction(PostUpdateCommands)
.WithoutBurst() // Destroys GameObjects
.ForEach((Entity entity, ref NamePlateOwner.State state) =>
{
var namePlate = NamePlateOwner.GetNamePlate(state.namePlateId);
NamePlateOwner.UnregisterNamePlate(state.namePlateId);
GameObject.Destroy(namePlate.gameObject);
PostUpdateCommands.RemoveComponent<NamePlateOwner.State>(entity);
}).Run();
PostUpdateCommands.Playback(EntityManager);
PostUpdateCommands.Dispose();
return default;
}
}
[UpdateInGroup(typeof(ClientLateUpdateGroup))]
[DisableAutoCreation]
[AlwaysSynchronizeSystem]
public class UpdateNamePlates : JobComponentSystem
{
EntityQuery LocalPlayerGroup;
protected override JobHandle OnUpdate(JobHandle inputDeps)
{
Entities
.ForEach((Entity e, ref LocalPlayer localPlayer) =>
{
if (localPlayer.playerEntity == Entity.Null)
return;
}).Run();
return default;
// TODO: mogensh I disabled this out when removing presentationentity
//
// Entities.ForEach((NamePlateOwner plateOwner, ref PresentationEntity presentation,
// ref NamePlateOwner.State state) =>
// {
// var namePlate = NamePlateOwner.GetNamePlate(state.namePlateId);
//
// if (namePlate == null)
// {
// GameDebug.LogError("namePlateOwner.namePlate == null");
// return;
// }
//
// var root = namePlate.namePlateRoot.gameObject;
//
// if (IngameHUD.showHud.IntValue == 0)
// {
// SetActiveIfNeeded(root, false);
// return;
// }
//
// if (!plateOwner.visible)
// {
// SetActiveIfNeeded(root, false);
// return;
// }
//
// // Dont show our own
// var character = presentation.ownerEntity;
// var localPlayerState = EntityManager.GetComponentData<Player.State>(localPlayer.playerEntity);
// if (character == localPlayerState.controlledEntity)
// {
// SetActiveIfNeeded(root, false);
// return;
// }
//
// // Dont show nameplate behinds
// var camera = Game.game.TopCamera(); // Camera.allCameras[0];
// var platePosWorld = plateOwner.namePlateTransform.position;
// var screenPos = camera.WorldToScreenPoint(platePosWorld);
// if (screenPos.z < 0)
// {
// SetActiveIfNeeded(root, false);
// return;
// }
//
// // Test occlusion
// var rayStart = camera.ScreenToWorldPoint(new Vector3(screenPos.x, screenPos.y, 0));
// var v = platePosWorld - rayStart;
// var distance = v.magnitude;
// const int defaultLayerMask = 1 << 0;
// var occluded = Physics.Raycast(rayStart, v.normalized, distance, defaultLayerMask);
//
// var friendly = plateOwner.team == localPlayerState.teamIndex;
// var color = friendly ? namePlate.friendColor : namePlate.enemyColor;
//
// var showPlate = friendly || !occluded;
//
// // Update plate
// if (!showPlate)
// {
// SetActiveIfNeeded(root, false);
// return;
// }
//
// namePlate.namePlateRoot.transform.position = screenPos;
//
// // Update icon
// var showIcon = friendly;
// SetActiveIfNeeded(namePlate.icon.gameObject, showIcon);
// if (showIcon)
// {
// namePlate.icon.color = color;
// }
//
// // Update name text
// var inNameTextDist = distance <= namePlate.maxNameDistance;
// var showNameText = !occluded && inNameTextDist;
// SetActiveIfNeeded(namePlate.nameText.gameObject, showNameText);
// if (showNameText)
// {
// namePlate.nameText.text = plateOwner.text;
// namePlate.nameText.color = color;
// }
//
// SetActiveIfNeeded(root, true);
// });
}
// Set settings active on UI Text creates garbage we check for whether active state has changed
void SetActiveIfNeeded(GameObject go, bool active)
{
if (go.activeSelf != active)
{
go.SetActive(active);
}
}
}