mirror of
https://github.com/GTA-ASM/SanAndreasUnity
synced 2024-11-26 22:10:17 +00:00
syncing works
This commit is contained in:
parent
f9e320ce23
commit
8d400bfceb
2 changed files with 124 additions and 4 deletions
|
@ -1,10 +1,19 @@
|
|||
using System.Collections.Generic;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Mirror;
|
||||
using SanAndreasUnity.Importing.Conversion;
|
||||
using SanAndreasUnity.Importing.Items;
|
||||
using SanAndreasUnity.Importing.Items.Definitions;
|
||||
using SanAndreasUnity.Net;
|
||||
using SanAndreasUnity.Utilities;
|
||||
using UnityEngine;
|
||||
using Object = UnityEngine.Object;
|
||||
using Random = UnityEngine.Random;
|
||||
|
||||
namespace SanAndreasUnity.Behaviours.Peds
|
||||
{
|
||||
public class DeadBody : MonoBehaviour
|
||||
public class DeadBody : NetworkBehaviour
|
||||
{
|
||||
private static List<DeadBody> _deadBodies = new List<DeadBody>();
|
||||
public static IEnumerable<DeadBody> DeadBodies => _deadBodies;
|
||||
|
@ -12,6 +21,18 @@ namespace SanAndreasUnity.Behaviours.Peds
|
|||
|
||||
public PushableByDamage PushableByDamage { get; private set; }
|
||||
|
||||
private Dictionary<int, Transform> m_framesDict = new Dictionary<int, Transform>();
|
||||
|
||||
[SyncVar] private int m_net_modelId;
|
||||
|
||||
private class SyncDictionaryIntVector3 : SyncDictionary<int, Vector3>
|
||||
{
|
||||
}
|
||||
|
||||
private SyncDictionaryIntVector3 m_syncDictionaryBonePositions = new SyncDictionaryIntVector3();
|
||||
private SyncDictionaryIntVector3 m_syncDictionaryBoneRotations = new SyncDictionaryIntVector3();
|
||||
|
||||
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
|
@ -29,6 +50,67 @@ namespace SanAndreasUnity.Behaviours.Peds
|
|||
_deadBodies.Remove(this);
|
||||
}
|
||||
|
||||
public override void OnStartClient()
|
||||
{
|
||||
if (NetStatus.IsServer)
|
||||
return;
|
||||
|
||||
F.RunExceptionSafe(this.InitialClientOnlySetup);
|
||||
}
|
||||
|
||||
private void InitialClientOnlySetup()
|
||||
{
|
||||
// load ped model
|
||||
|
||||
// apply initial bones sync data (because not all bones have rigid bodies)
|
||||
|
||||
// apply initial ragdoll (rigid bodies) sync data - this should be done AFTER applying bones sync data
|
||||
|
||||
|
||||
|
||||
|
||||
var def = Item.GetDefinition<PedestrianDef>(m_net_modelId);
|
||||
if (null == def)
|
||||
{
|
||||
Debug.LogError($"Failed to initialize dead body: ped definition not found by id {m_net_modelId}");
|
||||
return;
|
||||
}
|
||||
|
||||
this.gameObject.name = $"dead body {m_net_modelId} {def.ModelName}";
|
||||
|
||||
var geoms = Geometry.Load(def.ModelName, def.TextureDictionaryName);
|
||||
var frames = geoms.AttachFrames(this.transform, MaterialFlags.Default);
|
||||
m_framesDict = frames.ToDictionary(f => f.BoneId, f => f.transform);
|
||||
|
||||
// apply initial transformation data to bones (at the moment when ragdoll was detached) - this is needed because not all bones have rigid bodies
|
||||
// attached, and so will not be moved/rotated by physics engine
|
||||
|
||||
foreach (var pair in m_framesDict)
|
||||
{
|
||||
if (m_syncDictionaryBonePositions.TryGetValue(pair.Key, out Vector3 pos))
|
||||
pair.Value.localPosition = pos;
|
||||
if (m_syncDictionaryBoneRotations.TryGetValue(pair.Key, out Vector3 rotation))
|
||||
pair.Value.localRotation = Quaternion.Euler(rotation);
|
||||
}
|
||||
|
||||
// register to dictionary callbacks
|
||||
RegisterDictionaryCallback(
|
||||
m_syncDictionaryBonePositions,
|
||||
(tr, pos) => tr.localPosition = pos);
|
||||
RegisterDictionaryCallback(
|
||||
m_syncDictionaryBoneRotations,
|
||||
(tr, rotation) => tr.localRotation = Quaternion.Euler(rotation));
|
||||
}
|
||||
|
||||
private void RegisterDictionaryCallback<T>(SyncDictionary<int, T> dict, System.Action<Transform, T> action)
|
||||
{
|
||||
dict.Callback += (op, key, item) => F.RunExceptionSafe(() =>
|
||||
{
|
||||
if (m_framesDict.TryGetValue(key, out Transform tr))
|
||||
action(tr, item);
|
||||
});
|
||||
}
|
||||
|
||||
public static DeadBody Create(Transform ragdollTransform, Ped ped)
|
||||
{
|
||||
NetStatus.ThrowIfNotOnServer();
|
||||
|
@ -42,9 +124,47 @@ namespace SanAndreasUnity.Behaviours.Peds
|
|||
|
||||
ragdollTransform.SetParent(ragdollGameObject.transform);
|
||||
|
||||
deadBody.m_framesDict = ragdollTransform.GetComponentsInChildren<Frame>()
|
||||
.ToDictionary(f => f.BoneId, f => f.transform);
|
||||
|
||||
deadBody.InitSyncVarsOnServer(ped);
|
||||
|
||||
NetManager.Spawn(ragdollGameObject);
|
||||
|
||||
return deadBody;
|
||||
}
|
||||
|
||||
private void InitSyncVarsOnServer(Ped ped)
|
||||
{
|
||||
m_net_modelId = ped.PedDef.Id;
|
||||
|
||||
// assign initial bones transformations
|
||||
foreach (var pair in m_framesDict)
|
||||
{
|
||||
m_syncDictionaryBonePositions.Add(pair.Key, pair.Value.localPosition);
|
||||
m_syncDictionaryBoneRotations.Add(pair.Key, pair.Value.localRotation.eulerAngles);
|
||||
}
|
||||
}
|
||||
|
||||
private void Update()
|
||||
{
|
||||
if (NetStatus.IsServer)
|
||||
{
|
||||
foreach (var pair in m_framesDict)
|
||||
{
|
||||
Vector3 pos = pair.Value.localPosition;
|
||||
Vector3 rotation = pair.Value.localRotation.eulerAngles;
|
||||
|
||||
if (m_syncDictionaryBonePositions[pair.Key] != pos)
|
||||
m_syncDictionaryBonePositions[pair.Key] = pos;
|
||||
if (m_syncDictionaryBoneRotations[pair.Key] != rotation)
|
||||
m_syncDictionaryBoneRotations[pair.Key] = rotation;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -383,7 +383,7 @@ namespace SanAndreasUnity.Behaviours
|
|||
|
||||
}
|
||||
|
||||
public GameObject DetachRagdoll(DamageInfo damageInfo)
|
||||
public DeadBody DetachRagdoll(DamageInfo damageInfo)
|
||||
{
|
||||
if (null == m_ragdollBuilder)
|
||||
return null;
|
||||
|
@ -435,7 +435,7 @@ namespace SanAndreasUnity.Behaviours
|
|||
// change layer
|
||||
ragdollTransform.gameObject.SetLayerRecursive(GameManager.DefaultLayerIndex);
|
||||
|
||||
return DeadBody.Create(ragdollTransform, m_ped).gameObject;
|
||||
return DeadBody.Create(ragdollTransform, m_ped);
|
||||
}
|
||||
|
||||
public float GetAmountOfDamageForBone(Transform boneTransform, float baseDamageValue)
|
||||
|
|
Loading…
Reference in a new issue