Skip to content

Commit

Permalink
fix: teleport not properly working
Browse files Browse the repository at this point in the history
  • Loading branch information
Kinerius committed Dec 14, 2023
1 parent c46b8e7 commit f47b985
Show file tree
Hide file tree
Showing 18 changed files with 166 additions and 90 deletions.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 0 additions & 6 deletions Explorer/Assets/DCL/Character/CharacterObject.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,6 @@ public class CharacterObject : MonoBehaviour, ICharacterObject
[field: SerializeField]
public CharacterController Controller { get; private set; }

public void Move(Vector3 globalPosition)
{
Vector3 delta = globalPosition - transform.position;
Controller.Move(delta);
}

[field: SerializeField]
public Transform CameraFocus { get; private set; }

Expand Down
2 changes: 0 additions & 2 deletions Explorer/Assets/DCL/Character/ICharacterObject.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,6 @@ public interface ICharacterObject
{
CharacterController Controller { get; }

void Move(Vector3 globalPosition);

Transform CameraFocus { get; }

Transform Transform { get; }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,9 @@ public class CharacterRigidTransform
// Current Normal of the slope
public Vector3 CurrentSlopeNormal;

// The last calculated platform delta
public Vector3 PlatformDelta;

// This flag is set when the rigidTransform is between 2 slopes
public bool IsStuck;

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
using UnityEngine;

namespace DCL.CharacterMotion.Components
{
public struct PlayerTeleportIntent
{
public Vector3 Position;

public PlayerTeleportIntent(Vector3 position)
{
Position = position;
}
}
}

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

38 changes: 38 additions & 0 deletions Explorer/Assets/DCL/CharacterMotion/Platforms/PlatformRaycast.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
using CrdtEcsBridge.Physics;
using DCL.CharacterMotion.Components;
using DCL.CharacterMotion.Settings;
using System.Runtime.CompilerServices;
using UnityEngine;

namespace DCL.CharacterMotion.Platforms
{
public static class PlatformRaycast
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void Execute(CharacterPlatformComponent platformComponent, float radius, Transform transform, ICharacterControllerSettings settings)
{
float rayDistance = settings.PlatformRaycastLength;
float halfDistance = (rayDistance * 0.5f) + radius;

var ray = new Ray
{
origin = transform.position + (Vector3.up * halfDistance),
direction = Vector3.down,
};

bool hasHit = Physics.SphereCast(ray, radius, out RaycastHit hitInfo, rayDistance + radius, PhysicsLayers.CHARACTER_ONLY_MASK);

if (hasHit)
{
if (platformComponent.CurrentPlatform != hitInfo.collider.transform)
{
platformComponent.CurrentPlatform = hitInfo.collider.transform;
platformComponent.LastPosition = platformComponent.CurrentPlatform.InverseTransformPoint(transform.position);
platformComponent.LastRotation = platformComponent.CurrentPlatform.InverseTransformDirection(transform.forward);
}
}
else
platformComponent.CurrentPlatform = null;
}
}
}

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,11 @@
using Arch.System;
using Arch.SystemGroups;
using Arch.SystemGroups.DefaultSystemGroups;
using CrdtEcsBridge.Physics;
using DCL.CharacterMotion.Components;
using DCL.CharacterMotion.Platforms;
using DCL.CharacterMotion.Settings;
using DCL.Diagnostics;
using ECS.Abstract;
using System.Runtime.CompilerServices;
using UnityEngine;

namespace DCL.CharacterMotion.Systems
Expand All @@ -26,12 +25,15 @@ protected override void Update(float t)
}

[Query]
[None(typeof(PlayerTeleportIntent))]
private void ResolvePlatformMovement(
in ICharacterControllerSettings settings,
ref CharacterPlatformComponent platformComponent,
ref CharacterRigidTransform rigidTransform,
ref CharacterController characterController)
{
rigidTransform.PlatformDelta = Vector3.zero;

if (!rigidTransform.IsGrounded)
{
platformComponent.CurrentPlatform = null;
Expand All @@ -40,7 +42,7 @@ private void ResolvePlatformMovement(

Transform transform = characterController.transform;

CheckPlatform(platformComponent, transform, settings);
PlatformRaycast.Execute(platformComponent, characterController.radius, transform, settings);

if (platformComponent.CurrentPlatform == null) return;

Expand All @@ -49,36 +51,8 @@ private void ResolvePlatformMovement(
Vector3 newGroundWorldPos = platformTransform.TransformPoint(platformComponent.LastPosition);
Vector3 newCharacterForward = platformTransform.TransformDirection(platformComponent.LastRotation);

Vector3 deltaPosition = newGroundWorldPos - transform.position;
characterController.Move(deltaPosition);
rigidTransform.PlatformDelta = newGroundWorldPos - transform.position;
transform.forward = newCharacterForward;
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static void CheckPlatform(CharacterPlatformComponent platformComponent, Transform transform, ICharacterControllerSettings settings)
{
float rayDistance = settings.PlatformRaycastLength;
float halfDistance = rayDistance * 0.5f;

var ray = new Ray
{
origin = transform.position + (Vector3.up * halfDistance),
direction = Vector3.down,
};

bool hasHit = Physics.Raycast(ray, out RaycastHit hitInfo, rayDistance, PhysicsLayers.CHARACTER_ONLY_MASK);

if (hasHit)
{
if (platformComponent.CurrentPlatform != hitInfo.collider.transform)
{
platformComponent.CurrentPlatform = hitInfo.collider.transform;
platformComponent.LastPosition = platformComponent.CurrentPlatform.InverseTransformPoint(transform.position);
platformComponent.LastRotation = platformComponent.CurrentPlatform.InverseTransformDirection(transform.forward);
}
}
else
platformComponent.CurrentPlatform = null;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,23 @@ private InterpolateCharacterSystem(World world) : base(world) { }
protected override void Update(float t)
{
InterpolateQuery(World, t);
TeleportPlayerQuery(World);
}

[Query]
private void TeleportPlayer(in Entity entity, in CharacterController controller, ref CharacterPlatformComponent platformComponent, in PlayerTeleportIntent teleportIntent)
{
// Teleport the character
controller.transform.position = teleportIntent.Position;

// Reset the current platform so we dont bounce back if we are touching the world plane
platformComponent.CurrentPlatform = null;

World.Remove<PlayerTeleportIntent>(entity);
}

[Query]
[None(typeof(PlayerTeleportIntent))]
private void Interpolate(
[Data] float dt,
in ICharacterControllerSettings settings,
Expand All @@ -50,19 +64,19 @@ private void Interpolate(
Vector3 movementDelta = rigidTransform.MoveVelocity.Velocity * dt;
Vector3 finalGravity = rigidTransform.IsOnASteepSlope && !rigidTransform.IsStuck ? rigidTransform.SlopeGravity : rigidTransform.GravityVelocity;
Vector3 gravityDelta = finalGravity * dt;
Vector3 platformDelta = rigidTransform.PlatformDelta;

// In order for some systems to work correctly we move the character horizontally and then vertically
CollisionFlags horizontalCollisionFlags = characterController.Move(movementDelta);
Vector3 prevPos = transform.position;
CollisionFlags verticalCollisionFlags = characterController.Move(gravityDelta + slopeModifier);
CollisionFlags collisionFlags = characterController.Move(movementDelta + gravityDelta + slopeModifier + platformDelta);
Vector3 deltaMovement = transform.position - prevPos;

bool hasGroundedFlag = deltaMovement.y <= 0 && (EnumUtils.HasFlag(verticalCollisionFlags, CollisionFlags.Below) || EnumUtils.HasFlag(horizontalCollisionFlags, CollisionFlags.Below));
bool hasGroundedFlag = deltaMovement.y <= 0 && EnumUtils.HasFlag(collisionFlags, CollisionFlags.Below);

if (!Mathf.Approximately(gravityDelta.y, 0f))
rigidTransform.IsGrounded = hasGroundedFlag || characterController.isGrounded;

rigidTransform.IsCollidingWithWall = EnumUtils.HasFlag(horizontalCollisionFlags, CollisionFlags.Sides);
rigidTransform.IsCollidingWithWall = EnumUtils.HasFlag(collisionFlags, CollisionFlags.Sides);

// If we are on a platform we save our local position
PlatformSaveLocalPosition.Execute(ref platformComponent, transform.position);
Expand Down
49 changes: 25 additions & 24 deletions Explorer/Assets/DCL/ParcelsService/DCL.ParcelsService.asmdef
Original file line number Diff line number Diff line change
@@ -1,26 +1,27 @@
{
"name": "DCL.ParcelsService",
"rootNamespace": "",
"references": [
"GUID:f51ebe6a0ceec4240a699833d6309b23",
"GUID:1d2c76eb8b48e0b40940e8b31a679ce1",
"GUID:8322ea9340a544c59ddc56d4793eac74",
"GUID:4794e238ed0f65142a4aea5848b513e5",
"GUID:fa7b3fdbb04d67549916da7bd2af58ab",
"GUID:e0eedfa2deb9406daf86fd8368728e39",
"GUID:d8b63aba1907145bea998dd612889d6b",
"GUID:9e314663ce958b746873cb22d57ede55",
"GUID:c80c82a8f4e04453b85fbab973d6774a",
"GUID:4725c02394ab4ce19f889e4e8001f989",
"GUID:3640f3c0b42946b0b8794a1ed8e06ca5"
],
"includePlatforms": [],
"excludePlatforms": [],
"allowUnsafeCode": false,
"overrideReferences": false,
"precompiledReferences": [],
"autoReferenced": true,
"defineConstraints": [],
"versionDefines": [],
"noEngineReferences": false
"name": "DCL.ParcelsService",
"rootNamespace": "",
"references": [
"GUID:f51ebe6a0ceec4240a699833d6309b23",
"GUID:1d2c76eb8b48e0b40940e8b31a679ce1",
"GUID:8322ea9340a544c59ddc56d4793eac74",
"GUID:4794e238ed0f65142a4aea5848b513e5",
"GUID:fa7b3fdbb04d67549916da7bd2af58ab",
"GUID:e0eedfa2deb9406daf86fd8368728e39",
"GUID:d8b63aba1907145bea998dd612889d6b",
"GUID:9e314663ce958b746873cb22d57ede55",
"GUID:c80c82a8f4e04453b85fbab973d6774a",
"GUID:4725c02394ab4ce19f889e4e8001f989",
"GUID:3640f3c0b42946b0b8794a1ed8e06ca5",
"GUID:007bff6000804d90ac597452fb69a4ee"
],
"includePlatforms": [],
"excludePlatforms": [],
"allowUnsafeCode": false,
"overrideReferences": false,
"precompiledReferences": [],
"autoReferenced": true,
"defineConstraints": [],
"versionDefines": [],
"noEngineReferences": false
}
2 changes: 1 addition & 1 deletion Explorer/Assets/DCL/ParcelsService/IRetrieveScene.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,6 @@ public interface IRetrieveScene
/// <returns>Null if the parcel does not belong to the real scene</returns>
UniTask<IpfsTypes.SceneEntityDefinition> ByParcelAsync(Vector2Int parcel, CancellationToken ct);

World World { set; }
World World { get; set; }
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ public partial class RetrieveSceneFromFixedRealm : IRetrieveScene
/// <summary>
/// World should be set when the realm is [re-]loaded
/// </summary>
public World World { private get; set; }
public World World { get; set; }

public async UniTask<IpfsTypes.SceneEntityDefinition> ByParcelAsync(Vector2Int parcel, CancellationToken ct)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ public class RetrieveSceneFromVolatileWorld : IRetrieveScene

private readonly IRealmData realmData;

public World World { private get; set; }
public World World { get; set; }

public RetrieveSceneFromVolatileWorld(IRealmData realmData)
{
Expand Down
28 changes: 20 additions & 8 deletions Explorer/Assets/DCL/ParcelsService/TeleportController.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
using Arch.Core;
using Arch.System;
using Cysharp.Threading.Tasks;
using DCL.Character;
using DCL.Character.Components;
using DCL.CharacterMotion.Components;
using Ipfs;
using System.Collections.Generic;
using System.Threading;
Expand All @@ -9,11 +12,11 @@

namespace DCL.ParcelsService
{
public class TeleportController : ITeleportController
public partial class TeleportController : ITeleportController
{
private readonly ICharacterObject characterObject;

private IRetrieveScene retrieveScene;
private World world;

public TeleportController(ICharacterObject characterObject)
{
Expand All @@ -25,7 +28,12 @@ public void InvalidateRealm()
retrieveScene = null;
}

public void OnRealmLoaded(IRetrieveScene retrieveScene, World world)
public void OnWorldLoaded(World world)
{
this.world = world;
}

public void OnRealmLoaded(IRetrieveScene retrieveScene)
{
this.retrieveScene = retrieveScene;
this.retrieveScene.World = world;
Expand Down Expand Up @@ -76,12 +84,9 @@ public async UniTask TeleportToSceneSpawnPointAsync(Vector2Int parcel, Cancellat
else
targetPosition = ParcelMathHelper.GetPositionByParcelPosition(parcel);

// Prevent conflict with Interpolation System
// TODO move this to the system

await UniTask.Yield(PlayerLoopTiming.LastPostLateUpdate);

characterObject.Move(targetPosition);
AddTeleportIntentQuery(retrieveScene.World, targetPosition);
}

private static Vector3 GetOffsetFromSpawnPoint(IpfsTypes.SceneMetadata.SpawnPoint spawnPoint)
Expand Down Expand Up @@ -115,7 +120,14 @@ static float GetMidPoint(float[] coordArray)
public void TeleportToParcel(Vector2Int parcel)
{
Vector3 characterPos = ParcelMathHelper.GetPositionByParcelPosition(parcel);
characterObject.Move(characterPos);
AddTeleportIntentQuery(world, characterPos);
}

[Query]
[All(typeof(PlayerComponent))]
private void AddTeleportIntent([Data] Vector3 position, in Entity entity)
{
world.Add(entity, new PlayerTeleportIntent(position));
}
}
}
Loading

0 comments on commit f47b985

Please sign in to comment.