179 lines
7.5 KiB
C#
179 lines
7.5 KiB
C#
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;
|
|
}
|
|
}
|