Add practice range: shooting, AK47, intro cinematic, dressed warehouse scene
- PortalTestDestination practice range: Valorant-style hitscan rifle (recoil, spray/bloom, reload, controller support), debug HUD, practice-dummy targets with head/body hitboxes, hit/death/respawn animations, procedural SFX/FX - AK47 model (Quaternius, CC0) held via Animator IK, with fire/reload/equip anims - Intro cinematic (camera shots, title card, target beam-in, GO hand-off) - Scene dressing editor pass: CC0 textures, props, warehouse roof, lighting and post-processing; custom stylized skybox shader - CharacterMovement: camera recoil, shoulder offset, cinematic control lock - Unity CLI pipeline package; plus in-progress chat/Rive/player changes Asset credits: Assets/Models/Props/PROPS_CREDITS.txt (3 CC-BY 3.0 props), Assets/Textures/Range/TEXTURES_LICENSE.txt, Assets/Resources/*/..._LICENSE.txt Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
c674d76549
commit
5fc9ebf1e6
@@ -0,0 +1,55 @@
|
||||
using Mirror;
|
||||
using UnityEngine;
|
||||
using UnityEngine.SceneManagement;
|
||||
|
||||
[RequireComponent(typeof(Collider))]
|
||||
[RequireComponent(typeof(NetworkIdentity))]
|
||||
public class LocalPortal : NetworkBehaviour
|
||||
{
|
||||
[SerializeField] private string destinationSceneName = "PortalTestDestination";
|
||||
[SerializeField] private string playerTag = "Player";
|
||||
|
||||
private bool transitionStarted;
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
Collider portalCollider = GetComponent<Collider>();
|
||||
portalCollider.isTrigger = true;
|
||||
|
||||
Debug.Log($"[LocalPortal] Initialized '{name}' in scene '{SceneManager.GetActiveScene().name}'. " +
|
||||
$"Position: {transform.position}, Trigger: {portalCollider.isTrigger}, Destination: '{destinationSceneName}'", this);
|
||||
}
|
||||
|
||||
[ServerCallback]
|
||||
private void OnTriggerEnter(Collider other)
|
||||
{
|
||||
Transform root = other.transform.root;
|
||||
|
||||
Debug.Log($"[LocalPortal] Trigger entered by '{other.name}' (root: '{root.name}', tag: '{root.tag}') " +
|
||||
$"at position {root.position}. Portal position: {transform.position}. " +
|
||||
$"Current scene: '{SceneManager.GetActiveScene().name}'", this);
|
||||
|
||||
if (transitionStarted) return;
|
||||
|
||||
if (!root.CompareTag(playerTag))
|
||||
{
|
||||
Debug.Log($"[LocalPortal] Ignoring '{root.name}' because its tag is '{root.tag}', expected '{playerTag}'.", this);
|
||||
return;
|
||||
}
|
||||
|
||||
if (string.IsNullOrWhiteSpace(destinationSceneName))
|
||||
{
|
||||
Debug.LogError("[LocalPortal] Destination scene is empty; scene transition cancelled.", this);
|
||||
return;
|
||||
}
|
||||
|
||||
transitionStarted = true;
|
||||
|
||||
Debug.Log(
|
||||
$"[LocalPortal] Server changing scene from '{SceneManager.GetActiveScene().name}' " +
|
||||
$"to '{destinationSceneName}' because '{root.name}' entered the portal.",
|
||||
this);
|
||||
|
||||
NetworkManager.singleton.ServerChangeScene(destinationSceneName);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 4c6db0d3908c87f489b0a73d378b8a48
|
||||
Reference in New Issue
Block a user