first commit
This commit is contained in:
178
NitroxClient/MonoBehaviours/IntroCinematicUpdater.cs
Normal file
178
NitroxClient/MonoBehaviours/IntroCinematicUpdater.cs
Normal file
@@ -0,0 +1,178 @@
|
||||
using System.Collections;
|
||||
using NitroxClient.GameLogic;
|
||||
using NitroxModel.Core;
|
||||
using UnityEngine;
|
||||
|
||||
namespace NitroxClient.MonoBehaviours;
|
||||
|
||||
public class IntroCinematicUpdater : MonoBehaviour
|
||||
{
|
||||
public static RemotePlayer Partner;
|
||||
private static Transform modelRoot;
|
||||
|
||||
private static readonly Transform playerTransform = Player.main.transform;
|
||||
private static readonly Quaternion rotateOtherSide = Quaternion.Euler(0, 180, 0);
|
||||
|
||||
private Transform introEndTarget;
|
||||
private Vector3 introRemoteEndPosition;
|
||||
private Transform[] seatPartsLeft;
|
||||
private Transform[] seatPartsRight;
|
||||
private Transform seatArmRestLeft;
|
||||
private Transform seatArmRestRight;
|
||||
private SkinnedMeshRenderer[] seatBarRendererRight = [];
|
||||
|
||||
private SkinnedMeshRenderer remotePlayerHeadRenderer;
|
||||
private GameObject remotePlayerCustomHead;
|
||||
private SkinnedMeshRenderer[] remoteRenders = [];
|
||||
|
||||
public void Awake()
|
||||
{
|
||||
if (Partner == null)
|
||||
{
|
||||
Log.Error($"[{nameof(IntroCinematicUpdater)}.Awake()]: Partner was null. Disabling MonoBehaviour.");
|
||||
enabled = false;
|
||||
return;
|
||||
}
|
||||
modelRoot = EscapePod.main.transform.Find("models/Life_Pod_damaged_03/root");
|
||||
Transform seatLeft = modelRoot.Find("life_pod_seat_01_left_damaged_jnt1");
|
||||
Transform seatRight = modelRoot.Find("life_pod_seat_01_right_damaged_jnt1");
|
||||
|
||||
seatPartsLeft = new[]
|
||||
{
|
||||
seatLeft.Find("life_pod_seat_01_left_damaged_jnt2"),
|
||||
seatLeft.Find("life_pod_seat_01_left_damaged_jnt3")
|
||||
};
|
||||
|
||||
seatPartsRight = new[]
|
||||
{
|
||||
seatRight.Find("life_pod_seat_01_right_damaged_jnt2"),
|
||||
seatRight.Find("life_pod_seat_01_right_damaged_jnt3")
|
||||
};
|
||||
|
||||
seatArmRestLeft = modelRoot.Find("life_pod_seat_01_left_damaged_jnt4/life_pod_seat_01_left_damaged_jnt5");
|
||||
seatArmRestRight = modelRoot.Find("life_pod_seat_01_right_damaged_jnt4/life_pod_seat_01_right_damaged_jnt5");
|
||||
|
||||
seatBarRendererRight = modelRoot.parent.Find("lifepod_damaged_03_geo/life_pod_seat_01_R").GetComponentsInChildren<SkinnedMeshRenderer>();
|
||||
|
||||
remoteRenders = Partner.PlayerModel.GetComponentsInChildren<SkinnedMeshRenderer>();
|
||||
remotePlayerHeadRenderer = Partner.PlayerModel.transform.Find("male_geo/diveSuit/diveSuit_head_geo").GetComponent<SkinnedMeshRenderer>();
|
||||
|
||||
remotePlayerCustomHead = Instantiate(new GameObject("diveSuit_custom_head_geo"), Partner.PlayerModel.transform.Find("export_skeleton/head_rig"));
|
||||
remotePlayerCustomHead.transform.localPosition = new Vector3(1.0941f, -0.1163f, -1.2107f);
|
||||
remotePlayerCustomHead.transform.localRotation = new Quaternion(-0.05750692f, -0.5272675f, -0.6740523f, -0.5141357f);
|
||||
|
||||
MeshFilter mesh = remotePlayerCustomHead.AddComponent<MeshFilter>();
|
||||
MeshRenderer meshRenderer = remotePlayerCustomHead.AddComponent<MeshRenderer>();
|
||||
mesh.mesh = remotePlayerHeadRenderer.sharedMesh;
|
||||
meshRenderer.materials = remotePlayerHeadRenderer.materials;
|
||||
remotePlayerCustomHead.SetActive(false);
|
||||
|
||||
bool isLeftPlayer = NitroxServiceLocator.Cache<LocalPlayer>.Value.PlayerId < Partner.PlayerId;
|
||||
introEndTarget = EscapePod.main.transform.Find("EscapePodCinematics/intro_end");
|
||||
Vector3 introEndDiff = isLeftPlayer ? new Vector3(0, 0, 0.3f) : new Vector3(0, 0, -0.3f);
|
||||
introRemoteEndPosition = introEndTarget.position - introEndDiff;
|
||||
introEndTarget.position += introEndDiff;
|
||||
}
|
||||
|
||||
private Vector3 remotePlayerDestinationPos;
|
||||
private Quaternion remotePlayerDestinationRot;
|
||||
|
||||
private bool shouldDisplaceLocalPlayer;
|
||||
private float localPlayerDisplacementTime;
|
||||
|
||||
private bool shouldDisplaceRemotePlayer;
|
||||
private Vector3 remotePlayerDisplacement = Vector3.zero;
|
||||
|
||||
private IEnumerator Start()
|
||||
{
|
||||
remoteRenders.ForEach(smr => smr.enabled = false);
|
||||
seatBarRendererRight.ForEach(smr => smr.updateWhenOffscreen = true);
|
||||
|
||||
yield return new WaitForSecondsRealtime(11f); //Local player in seat
|
||||
remoteRenders.ForEach(smr => smr.enabled = true);
|
||||
|
||||
yield return new WaitForSecondsRealtime(33.45f - 11f); //Remote Player deadly hit => disable original head
|
||||
remotePlayerHeadRenderer.enabled = false;
|
||||
|
||||
yield return new WaitForSecondsRealtime(33.58f - 33.45f); //Remote Player visible => enable custom head
|
||||
remotePlayerCustomHead.SetActive(true);
|
||||
|
||||
yield return new WaitForSecondsRealtime(40f - 33.58f); //Seatbelt appears => enable position sync & switch to original head
|
||||
remotePlayerCustomHead.SetActive(false);
|
||||
remotePlayerHeadRenderer.enabled = true;
|
||||
Destroy(remotePlayerCustomHead);
|
||||
|
||||
yield return new WaitForSecondsRealtime(50.5f - 40f); //Slowly move remote player backwards
|
||||
shouldDisplaceRemotePlayer = true;
|
||||
|
||||
yield return new WaitForSecondsRealtime(50.72f - 50.5f); //Disable and move remote player
|
||||
shouldDisplaceRemotePlayer = false;
|
||||
remotePlayerDisplacement = Vector3.zero;
|
||||
remoteRenders.ForEach(smr => smr.enabled = false);
|
||||
|
||||
yield return new WaitForSecondsRealtime(53f - 50.72f); //Slowly move local player to modified cin-end
|
||||
shouldDisplaceLocalPlayer = true;
|
||||
}
|
||||
|
||||
private void LateUpdate()
|
||||
{
|
||||
Vector3 modelRootPos = modelRoot.position;
|
||||
Quaternion modelRootRot = modelRoot.rotation;
|
||||
|
||||
// Coping the global rotation, inverting the y and adding 180° to it
|
||||
Quaternion InverseRotateAroundEscapePod(Quaternion from)
|
||||
{
|
||||
Quaternion offset = Quaternion.Inverse(modelRootRot) * from;
|
||||
return modelRootRot * rotateOtherSide * new Quaternion(-offset.x, offset.y, offset.z, -offset.w);
|
||||
}
|
||||
|
||||
// Mirror animate the remote like the local player
|
||||
Vector3 posDiff = playerTransform.position - modelRootPos;
|
||||
remotePlayerDestinationPos = modelRootPos + new Vector3(posDiff.x, posDiff.y, -posDiff.z) + remotePlayerDisplacement;
|
||||
remotePlayerDestinationRot = InverseRotateAroundEscapePod(playerTransform.rotation);
|
||||
transform.SetPositionAndRotation(remotePlayerDestinationPos, remotePlayerDestinationRot);
|
||||
|
||||
// Mirror animate the seat parts and stop it before the animation ends so the SN animator resets our manipulations
|
||||
if (!shouldDisplaceLocalPlayer)
|
||||
{
|
||||
for (int i = 0; i < seatPartsLeft.Length; i++)
|
||||
{
|
||||
seatPartsRight[i].localRotation = seatPartsLeft[i].localRotation;
|
||||
}
|
||||
|
||||
seatArmRestRight.localPosition = -seatArmRestLeft.localPosition;
|
||||
}
|
||||
|
||||
if (shouldDisplaceRemotePlayer) remotePlayerDisplacement += new Vector3(0, 0, 0.05f);
|
||||
|
||||
if (shouldDisplaceLocalPlayer)
|
||||
{
|
||||
Vector3 introEndTargetPos = introEndTarget.position;
|
||||
playerTransform.position = Vector3.Lerp(playerTransform.position, introEndTargetPos, localPlayerDisplacementTime);
|
||||
MainCameraControl.main.transform.position = Vector3.Lerp(MainCameraControl.main.transform.position, introEndTargetPos, localPlayerDisplacementTime);
|
||||
|
||||
localPlayerDisplacementTime += 0.01f;
|
||||
}
|
||||
}
|
||||
|
||||
private void OnDestroy()
|
||||
{
|
||||
foreach (SkinnedMeshRenderer renderer in remoteRenders)
|
||||
{
|
||||
if (renderer)
|
||||
{
|
||||
renderer.enabled = true;
|
||||
}
|
||||
}
|
||||
|
||||
foreach (SkinnedMeshRenderer renderer in seatBarRendererRight)
|
||||
{
|
||||
if (renderer)
|
||||
{
|
||||
renderer.updateWhenOffscreen = false;
|
||||
}
|
||||
}
|
||||
|
||||
transform.position = introRemoteEndPosition;
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user