Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: teleport not properly working #210

Merged
merged 2 commits into from
Dec 18, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view

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.

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);
Kinerius marked this conversation as resolved.
Show resolved Hide resolved

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