浏览代码

Host mode movement and interpolation (no networking sync yet)

/main
Luke Stampfli 4 年前
当前提交
208a3a8a
共有 17 个文件被更改,包括 393 次插入7 次删除
  1. 64
      Assets/Prefabs/PlayerCharacter.prefab
  2. 58
      Assets/Scenes/SampleScene.unity
  3. 8
      Assets/Scenes/SampleScene.meta
  4. 2
      Assets/Scenes/SampleScene/NavMesh.asset
  5. 8
      Assets/Scenes/SampleScene/NavMesh.asset.meta
  6. 77
      Assets/Scripts/Character.cs
  7. 11
      Assets/Scripts/Character.cs.meta
  8. 25
      Assets/Scripts/Interpolation.cs
  9. 11
      Assets/Scripts/Interpolation.cs.meta
  10. 40
      Assets/Scripts/PlayerInput.cs
  11. 11
      Assets/Scripts/PlayerInput.cs.meta
  12. 14
      Assets/Scripts/PositionInterpolation.cs
  13. 11
      Assets/Scripts/PositionInterpolation.cs.meta
  14. 49
      Assets/Scripts/SimulationManager.cs
  15. 11
      Assets/Scripts/SimulationManager.cs.meta

64
Assets/Prefabs/PlayerCharacter.prefab


- component: {fileID: 922472105905938413}
- component: {fileID: 922472105905938415}
- component: {fileID: 922472105905938414}
- component: {fileID: 901965000}
- component: {fileID: 2483890359039831193}
- component: {fileID: -7978990056136126243}
m_Layer: 0
m_Name: PlayerCharacter
m_TagString: Untagged

m_Interpolate: 0
m_Constraints: 0
m_CollisionDetection: 0
--- !u!195 &901965000
NavMeshAgent:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 922472105905938403}
m_Enabled: 1
m_AgentTypeID: 0
m_Radius: 0.5
m_Speed: 3.5
m_Acceleration: 8
avoidancePriority: 50
m_AngularSpeed: 120
m_StoppingDistance: 0
m_AutoTraverseOffMeshLink: 1
m_AutoBraking: 1
m_AutoRepath: 1
m_Height: 2
m_BaseOffset: 0
m_WalkableMask: 4294967295
m_ObstacleAvoidanceType: 4
--- !u!114 &2483890359039831193
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 922472105905938403}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 5ef335173735a554a98a17d4ef9b21c2, type: 3}
m_Name:
m_EditorClassIdentifier:
movementSpeed: 5
movementTarget: {x: 2, y: 0, z: 2}
--- !u!114 &-7978990056136126243
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 922472105905938403}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 0eaaa5f4790dfc64ebc62ee85984bab9, type: 3}
m_Name:
m_EditorClassIdentifier:
--- !u!1 &2312369181857326860
GameObject:
m_ObjectHideFlags: 0

serializedVersion: 6
m_Component:
- component: {fileID: 308914464942347706}
- component: {fileID: 2501205002747161907}
m_Layer: 0
m_Name: Graphics
m_TagString: Untagged

m_Father: {fileID: 922472105905938412}
m_RootOrder: 0
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!114 &2501205002747161907
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 4347399796013429617}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 7dac193e15c19dd47bcfb78c85bd6d8d, type: 3}
m_Name:
m_EditorClassIdentifier:

58
Assets/Scenes/SampleScene.unity


preserveTilesOutsideBounds: 0
debug:
m_Flags: 0
m_NavMeshData: {fileID: 0}
m_NavMeshData: {fileID: 23800000, guid: c7720ceef5c5df34c98168df9d4f695e, type: 2}
--- !u!1 &532797402
GameObject:
m_ObjectHideFlags: 0

m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_StaticEditorFlags: 4294967295
m_IsActive: 1
--- !u!64 &532797403
MeshCollider:

m_GameObject: {fileID: 532797402}
m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
m_LocalPosition: {x: 0, y: -1, z: 10}
m_LocalScale: {x: 1, y: 1, z: 1}
m_LocalScale: {x: 2, y: 2, z: 2}
m_Children: []
m_Father: {fileID: 1233618361}
m_RootOrder: 0

m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_StaticEditorFlags: 4294967295
m_IsActive: 1
--- !u!108 &705507994
Light:

PlayerPrefabHash:
id: 0
CreatePlayerPrefab: 1
ReceiveTickrate: 20
ReceiveTickrate: 0
EventTickrate: 20
EventTickrate: 0
MaxObjectUpdatesPerTick: -1
ClientConnectionBufferTimeout: 10
ConnectionApproval: 0

m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_StaticEditorFlags: 4294967295
m_IsActive: 1
--- !u!4 &1233618361
Transform:

m_Father: {fileID: 0}
m_RootOrder: 1
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!1 &1601651753
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 1601651754}
- component: {fileID: 1601651755}
m_Layer: 0
m_Name: SimulationManager
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!4 &1601651754
Transform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1601651753}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children: []
m_Father: {fileID: 0}
m_RootOrder: 3
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!114 &1601651755
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1601651753}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 3e6c31da8c35c2743b0311f50e3e1a69, type: 3}
m_Name:
m_EditorClassIdentifier:
tickRate: 20

8
Assets/Scenes/SampleScene.meta


fileFormatVersion: 2
guid: d35e52e80fddfa34e8598be81bb477bb
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

2
Assets/Scenes/SampleScene/NavMesh.asset
文件差异内容过多而无法显示
查看文件

8
Assets/Scenes/SampleScene/NavMesh.asset.meta


fileFormatVersion: 2
guid: c7720ceef5c5df34c98168df9d4f695e
NativeFormatImporter:
externalObjects: {}
mainObjectFileID: 0
userData:
assetBundleName:
assetBundleVariant:

77
Assets/Scripts/Character.cs


using MLAPI;
using System;
using System.IO;
using System.Linq;
using UnityEngine;
using UnityEngine.AI;
public class Character : NetworkedBehaviour
{
[SerializeField]
private float movementSpeed;
private NavMeshAgent _navMeshAgent;
private NavMeshPath _path;
private PositionInterpolation _interpolation;
public void Awake()
{
_path = new NavMeshPath();
_navMeshAgent = GetComponent<NavMeshAgent>();
_interpolation = GetComponentInChildren<PositionInterpolation>();
}
///<inheritdoc/>
public override void NetworkStart()
{
base.NetworkStart();
SimulationManager.Singleton.OnSimulationUpdate += SimulationUpdate;
SimulationManager.Singleton.OnSyncNetworkEvents += SyncNetworkEvents;
_navMeshAgent.updateRotation = false;
_navMeshAgent.updatePosition = true;
if (!IsServer)
{
Destroy(_navMeshAgent);
}
SetMovementTarget(new Vector3(5, 0, 5));
}
private void SyncNetworkEvents(float time, float deltaTime)
{
_interpolation.AddValue(time, transform.position);
}
public void SetMovementTarget(Vector3 position)
{
_navMeshAgent.CalculatePath(position, _path);
}
private void SimulationUpdate(float time, float deltaTime)
{
if (IsServer)
{
NavigationMovement(deltaTime);
}
}
private void NavigationMovement(float deltaTime)
{
var corners = _path.corners; // TODO: maybe use non-alloc version
if (corners.Any() && Vector3.SqrMagnitude(corners[corners.Length - 1]- transform.position) < 1)
{
_path = new NavMeshPath();
corners = _path.corners;
}
var direction = corners.Length > 1 ? (corners[1]- corners[0]).normalized : Vector3.zero;
var movement = direction * movementSpeed * deltaTime;
_navMeshAgent.Move(movement);
}
}

11
Assets/Scripts/Character.cs.meta


fileFormatVersion: 2
guid: 5ef335173735a554a98a17d4ef9b21c2
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

25
Assets/Scripts/Interpolation.cs


using System;
using UnityEngine;
public abstract class Interpolation<T> : MonoBehaviour
{
public abstract Func<T, T, float, T> LerpFunction { get;}
private (float, T) _last;
private (float, T) _previous;
public T GetValueForTime(float time)
{
float timeSincePrevious = time - _previous.Item1;
float t = (timeSincePrevious / (_last.Item1 - _previous.Item1) - 1f);
return LerpFunction(_previous.Item2, _last.Item2, t);
}
public void AddValue(float time, T value)
{
_previous = _last;
_last = (time, value);
}
}

11
Assets/Scripts/Interpolation.cs.meta


fileFormatVersion: 2
guid: 4be874942db508e4bb7c4481d0ffb727
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

40
Assets/Scripts/PlayerInput.cs


using MLAPI;
using MLAPI.Messaging;
using System;
using UnityEngine;
public class PlayerInput : NetworkedBehaviour
{
private Character character;
public void Awake()
{
character = GetComponent<Character>();
}
public override void NetworkStart()
{
if (IsClient)
{
SimulationManager.Singleton.OnSimulationUpdate += SimulationUpdate;
}
}
private void SimulationUpdate(float time, float deltaTime)
{
if (Input.GetMouseButton(0))
{
RaycastHit hit;
if (Physics.Raycast(Camera.main.ScreenPointToRay(Input.mousePosition), out hit))
{
InvokeServerRpc(SendPlayerInput, hit.point);
}
}
}
[ServerRPC]
public void SendPlayerInput(Vector3 position)
{
character.SetMovementTarget(position);
}
}

11
Assets/Scripts/PlayerInput.cs.meta


fileFormatVersion: 2
guid: 0eaaa5f4790dfc64ebc62ee85984bab9
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

14
Assets/Scripts/PositionInterpolation.cs


using System;
using UnityEngine;
using MLAPI;
[DefaultExecutionOrder(200)]
public class PositionInterpolation : Interpolation<Vector3>
{
public override Func<Vector3, Vector3, float, Vector3> LerpFunction => Vector3.LerpUnclamped;
private void Update()
{
transform.position = GetValueForTime(NetworkingManager.Singleton.NetworkTime);
}
}

11
Assets/Scripts/PositionInterpolation.cs.meta


fileFormatVersion: 2
guid: 7dac193e15c19dd47bcfb78c85bd6d8d
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

49
Assets/Scripts/SimulationManager.cs


using MLAPI;
using UnityEngine;
[DefaultExecutionOrder(100)]
public class SimulationManager : MonoBehaviour
{
public static SimulationManager Singleton { get; private set; }
public delegate void SimulationUpdateDelegate(float time, float deltaTime);
/// <summary>
/// Main game simulation such as processing inputs, running AI, ticking state machines etc. An event is definitely not what we want to use because we have no order, but FixedUpdate isn't as well.
/// </summary>
public event SimulationUpdateDelegate OnSimulationUpdate;
/// <summary>
/// Called after simulation is done replicate game state such as positions to the client.
/// </summary>
public event SimulationUpdateDelegate OnSyncNetworkEvents;
[SerializeField]
private int tickRate = 20;
private float _networkTickDelta;
private float _lastNetworkTickTime;
private void OnEnable()
{
Singleton = this;
_networkTickDelta = 1f / tickRate;
}
// Update is called once per frame
void Update()
{
// The goal here is to sync this up with MLAPIs synchronization but the current network tick model in MLAPI is broken.
while (NetworkingManager.Singleton.NetworkTime - _lastNetworkTickTime >= _networkTickDelta)
{
_lastNetworkTickTime += _networkTickDelta;
Physics.Simulate(_networkTickDelta);
OnSimulationUpdate?.Invoke(_lastNetworkTickTime,_networkTickDelta);
OnSyncNetworkEvents?.Invoke(_lastNetworkTickTime, _networkTickDelta);
}
}
}

11
Assets/Scripts/SimulationManager.cs.meta


fileFormatVersion: 2
guid: 3e6c31da8c35c2743b0311f50e3e1a69
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
正在加载...
取消
保存