Added new Rocket-Processing
This commit is contained in:
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
Binary file not shown.
Binary file not shown.
@@ -1,130 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 4fc513ed8ad88954f9f2c7cbfdaca09a
|
||||
TextureImporter:
|
||||
internalIDToNameTable: []
|
||||
externalObjects: {}
|
||||
serializedVersion: 13
|
||||
mipmaps:
|
||||
mipMapMode: 0
|
||||
enableMipMap: 0
|
||||
sRGBTexture: 1
|
||||
linearTexture: 0
|
||||
fadeOut: 0
|
||||
borderMipMap: 0
|
||||
mipMapsPreserveCoverage: 0
|
||||
alphaTestReferenceValue: 0.5
|
||||
mipMapFadeDistanceStart: 1
|
||||
mipMapFadeDistanceEnd: 3
|
||||
bumpmap:
|
||||
convertToNormalMap: 0
|
||||
externalNormalMap: 0
|
||||
heightScale: 0.25
|
||||
normalMapFilter: 0
|
||||
flipGreenChannel: 0
|
||||
isReadable: 0
|
||||
streamingMipmaps: 0
|
||||
streamingMipmapsPriority: 0
|
||||
vTOnly: 0
|
||||
ignoreMipmapLimit: 0
|
||||
grayScaleToAlpha: 0
|
||||
generateCubemap: 6
|
||||
cubemapConvolution: 0
|
||||
seamlessCubemap: 0
|
||||
textureFormat: 1
|
||||
maxTextureSize: 2048
|
||||
textureSettings:
|
||||
serializedVersion: 2
|
||||
filterMode: 1
|
||||
aniso: 1
|
||||
mipBias: 0
|
||||
wrapU: 1
|
||||
wrapV: 1
|
||||
wrapW: 1
|
||||
nPOTScale: 1
|
||||
lightmap: 0
|
||||
compressionQuality: 50
|
||||
spriteMode: 0
|
||||
spriteExtrude: 1
|
||||
spriteMeshType: 1
|
||||
alignment: 0
|
||||
spritePivot: {x: 0.5, y: 0.5}
|
||||
spritePixelsToUnits: 100
|
||||
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
|
||||
spriteGenerateFallbackPhysicsShape: 1
|
||||
alphaUsage: 0
|
||||
alphaIsTransparency: 0
|
||||
spriteTessellationDetail: -1
|
||||
textureType: 6
|
||||
textureShape: 1
|
||||
singleChannelComponent: 0
|
||||
flipbookRows: 1
|
||||
flipbookColumns: 1
|
||||
maxTextureSizeSet: 0
|
||||
compressionQualitySet: 0
|
||||
textureFormatSet: 0
|
||||
ignorePngGamma: 0
|
||||
applyGammaDecoding: 0
|
||||
swizzle: 50462976
|
||||
cookieLightType: 0
|
||||
platformSettings:
|
||||
- serializedVersion: 4
|
||||
buildTarget: DefaultTexturePlatform
|
||||
maxTextureSize: 4096
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
ignorePlatformSupport: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
forceMaximumCompressionQuality_BC6H_BC7: 0
|
||||
- serializedVersion: 4
|
||||
buildTarget: Standalone
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
ignorePlatformSupport: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
forceMaximumCompressionQuality_BC6H_BC7: 0
|
||||
- serializedVersion: 4
|
||||
buildTarget: Android
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
ignorePlatformSupport: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
forceMaximumCompressionQuality_BC6H_BC7: 0
|
||||
spriteSheet:
|
||||
serializedVersion: 2
|
||||
sprites: []
|
||||
outline: []
|
||||
customData:
|
||||
physicsShape: []
|
||||
bones: []
|
||||
spriteID:
|
||||
internalID: 0
|
||||
vertices: []
|
||||
indices:
|
||||
edges: []
|
||||
weights: []
|
||||
secondaryTextures: []
|
||||
spriteCustomMetadata:
|
||||
entries: []
|
||||
nameFileIdTable: {}
|
||||
mipmapLimitGroupName:
|
||||
pSDRemoveMatte: 0
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
|
||||
Binary file not shown.
@@ -15,4 +15,5 @@ MonoBehaviour:
|
||||
itemId: rocket-back-standart-ready
|
||||
displayName: Rocket-Back-Standart-Ready
|
||||
category: 2
|
||||
isAssemblyReady: 1
|
||||
worldPrefab: {fileID: 5195529150077527847, guid: ea8e439364ce6aa4dab3586bae0edfed, type: 3}
|
||||
|
||||
@@ -15,4 +15,5 @@ MonoBehaviour:
|
||||
itemId: rocket-base-avia-ready
|
||||
displayName: Rocket-Base-Avia-Ready
|
||||
category: 2
|
||||
isAssemblyReady: 1
|
||||
worldPrefab: {fileID: 1256934312238460503, guid: 9712e2459410a6d43b55ea9d3847e29a, type: 3}
|
||||
|
||||
@@ -15,4 +15,5 @@ MonoBehaviour:
|
||||
itemId: rocket-base-standart-ready
|
||||
displayName: Rocket-Base-Standart-Ready
|
||||
category: 2
|
||||
isAssemblyReady: 1
|
||||
worldPrefab: {fileID: 875723161486981202, guid: 6e681ca5358fff648ba85ae9e494fa77, type: 3}
|
||||
|
||||
@@ -15,4 +15,5 @@ MonoBehaviour:
|
||||
itemId: rocket-cone-standart-ready
|
||||
displayName: Rocket-Cone-Standart-Ready
|
||||
category: 2
|
||||
isAssemblyReady: 1
|
||||
worldPrefab: {fileID: 7151289907260619783, guid: a31204f69b185d54ab9e12b0a3a1e98b, type: 3}
|
||||
|
||||
@@ -66,11 +66,16 @@ public sealed class NetworkDraggableInteractable : NetworkInteractable, IWorksta
|
||||
NetworkVariableWritePermission.Server);
|
||||
|
||||
private readonly HashSet<Collider> ignoredPlayerColliders = new();
|
||||
private readonly HashSet<Collider> desiredIgnoredColliders = new();
|
||||
private readonly List<Collider> collidersToRestore = new();
|
||||
private readonly RaycastHit[] groundHits = new RaycastHit[16];
|
||||
private float nextCollisionRefreshTime;
|
||||
private Vector3 localGroundContactPoint;
|
||||
private Vector3 smoothedGroundNormal = Vector3.up;
|
||||
private Vector3 dragVelocity;
|
||||
private float dragWorldHeight;
|
||||
private bool hasDragReferenceHeight;
|
||||
private bool initialUseGravity;
|
||||
private CollisionDetectionMode initialCollisionDetectionMode;
|
||||
|
||||
public float Weight => weight;
|
||||
public int ActiveDraggerCount
|
||||
@@ -125,6 +130,12 @@ public sealed class NetworkDraggableInteractable : NetworkInteractable, IWorksta
|
||||
{
|
||||
ResolvePhysicsReferences();
|
||||
ApplyWeight();
|
||||
|
||||
if (physicsBody != null)
|
||||
{
|
||||
initialUseGravity = physicsBody.useGravity;
|
||||
initialCollisionDetectionMode = physicsBody.collisionDetectionMode;
|
||||
}
|
||||
}
|
||||
|
||||
private void OnValidate()
|
||||
@@ -157,7 +168,7 @@ public sealed class NetworkDraggableInteractable : NetworkInteractable, IWorksta
|
||||
return;
|
||||
|
||||
nextCollisionRefreshTime = Time.time + collisionRefreshInterval;
|
||||
IgnoreCollisionsWithPlayers();
|
||||
RefreshDraggerCollisions();
|
||||
}
|
||||
|
||||
private void FixedUpdate()
|
||||
@@ -168,10 +179,7 @@ public sealed class NetworkDraggableInteractable : NetworkInteractable, IWorksta
|
||||
RemoveInvalidDraggers();
|
||||
if (!HasEnoughPullStrength ||
|
||||
!TryGetCombinedDragTarget(out Vector3 target, out Vector3 forward))
|
||||
{
|
||||
dragVelocity = Vector3.zero;
|
||||
return;
|
||||
}
|
||||
|
||||
float totalStrength = ActiveDraggerCount * pullStrengthPerPlayer;
|
||||
float loadRatio = Mathf.Clamp01(weight / totalStrength);
|
||||
@@ -181,7 +189,7 @@ public sealed class NetworkDraggableInteractable : NetworkInteractable, IWorksta
|
||||
switch (movementMode)
|
||||
{
|
||||
case DraggableMovementMode.KeepWorldHeight:
|
||||
target.y = physicsBody.position.y;
|
||||
target.y = dragWorldHeight;
|
||||
FollowDragTarget(target, forward, movementSpeed, Vector3.up);
|
||||
break;
|
||||
|
||||
@@ -360,6 +368,21 @@ public sealed class NetworkDraggableInteractable : NetworkInteractable, IWorksta
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool TryReleaseExternalControlToPlayer(ulong clientId)
|
||||
{
|
||||
if (!IsServer || !IsSpawned || !IsExternallyControlled ||
|
||||
TryGetDraggedObject(clientId, this, out _) ||
|
||||
!TryGetPlayerObject(clientId, out _))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
isExternallyControlled.Value = false;
|
||||
AddDragger(clientId);
|
||||
ApplyDraggingState();
|
||||
return IsDragger(clientId);
|
||||
}
|
||||
|
||||
[Rpc(SendTo.Server, InvokePermission = RpcInvokePermission.Everyone)]
|
||||
private void RequestReleaseRpc(RpcParams rpcParams = default)
|
||||
{
|
||||
@@ -379,34 +402,52 @@ public sealed class NetworkDraggableInteractable : NetworkInteractable, IWorksta
|
||||
{
|
||||
if (physicsBody != null)
|
||||
{
|
||||
bool shouldBeKinematic = HasAnyDragger || IsExternallyControlled || !IsServer;
|
||||
bool shouldBeKinematic = IsExternallyControlled || !IsServer;
|
||||
|
||||
if (physicsBody.isKinematic && !shouldBeKinematic)
|
||||
if (shouldBeKinematic)
|
||||
{
|
||||
physicsBody.collisionDetectionMode = CollisionDetectionMode.ContinuousSpeculative;
|
||||
physicsBody.isKinematic = true;
|
||||
physicsBody.useGravity = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
physicsBody.isKinematic = false;
|
||||
physicsBody.useGravity = initialUseGravity;
|
||||
physicsBody.collisionDetectionMode = ResolveDynamicCollisionDetectionMode();
|
||||
}
|
||||
|
||||
if (!physicsBody.isKinematic)
|
||||
if (IsExternallyControlled)
|
||||
{
|
||||
physicsBody.linearVelocity = Vector3.zero;
|
||||
physicsBody.angularVelocity = Vector3.zero;
|
||||
}
|
||||
|
||||
physicsBody.isKinematic = shouldBeKinematic;
|
||||
}
|
||||
|
||||
if (HasAnyDragger || IsExternallyControlled)
|
||||
if (HasAnyDragger)
|
||||
{
|
||||
dragVelocity = Vector3.zero;
|
||||
if (!hasDragReferenceHeight && physicsBody != null)
|
||||
{
|
||||
dragWorldHeight = physicsBody.position.y;
|
||||
hasDragReferenceHeight = true;
|
||||
}
|
||||
|
||||
CacheGroundContactPoint();
|
||||
smoothedGroundNormal = physicsBody != null ? physicsBody.transform.up : Vector3.up;
|
||||
IgnoreCollisionsWithPlayers();
|
||||
RefreshDraggerCollisions();
|
||||
}
|
||||
else
|
||||
{
|
||||
dragVelocity = Vector3.zero;
|
||||
hasDragReferenceHeight = false;
|
||||
RestorePlayerCollisions();
|
||||
}
|
||||
}
|
||||
|
||||
private CollisionDetectionMode ResolveDynamicCollisionDetectionMode() =>
|
||||
initialCollisionDetectionMode == CollisionDetectionMode.Discrete
|
||||
? CollisionDetectionMode.ContinuousDynamic
|
||||
: initialCollisionDetectionMode;
|
||||
|
||||
private void ResolvePhysicsReferences()
|
||||
{
|
||||
if (physicsBody == null)
|
||||
@@ -430,16 +471,11 @@ public sealed class NetworkDraggableInteractable : NetworkInteractable, IWorksta
|
||||
float movementSpeed,
|
||||
Vector3 surfaceNormal)
|
||||
{
|
||||
Vector3 nextPosition = Vector3.SmoothDamp(
|
||||
physicsBody.position,
|
||||
DrivePhysicsBody(
|
||||
target,
|
||||
ref dragVelocity,
|
||||
positionSmoothTime,
|
||||
CalculateDragRotation(forward, surfaceNormal),
|
||||
movementSpeed,
|
||||
Time.fixedDeltaTime);
|
||||
|
||||
physicsBody.MovePosition(nextPosition);
|
||||
physicsBody.MoveRotation(CalculateDragRotation(forward, surfaceNormal));
|
||||
movementSpeed);
|
||||
}
|
||||
|
||||
private void MoveAlongGround(
|
||||
@@ -449,18 +485,10 @@ public sealed class NetworkDraggableInteractable : NetworkInteractable, IWorksta
|
||||
{
|
||||
Vector3 currentPosition = physicsBody.position;
|
||||
Vector3 planarTarget = new(dragTarget.x, currentPosition.y, dragTarget.z);
|
||||
Vector3 planarVelocity = new(dragVelocity.x, 0f, dragVelocity.z);
|
||||
Vector3 nextPlanarPosition = Vector3.SmoothDamp(
|
||||
currentPosition,
|
||||
planarTarget,
|
||||
ref planarVelocity,
|
||||
positionSmoothTime,
|
||||
movementSpeed,
|
||||
Time.fixedDeltaTime);
|
||||
nextPlanarPosition.y = currentPosition.y;
|
||||
dragVelocity = new Vector3(planarVelocity.x, dragVelocity.y, planarVelocity.z);
|
||||
|
||||
Vector3 probePosition = nextPlanarPosition;
|
||||
Vector3 planarStep = Vector3.ClampMagnitude(
|
||||
planarTarget - currentPosition,
|
||||
movementSpeed * Time.fixedDeltaTime);
|
||||
Vector3 probePosition = currentPosition + planarStep;
|
||||
|
||||
if (!TryGetGroundSurface(probePosition, out Vector3 groundPoint, out Vector3 groundNormal))
|
||||
return;
|
||||
@@ -469,14 +497,55 @@ public sealed class NetworkDraggableInteractable : NetworkInteractable, IWorksta
|
||||
Vector3 scaledContactPoint = Vector3.Scale(localGroundContactPoint, physicsBody.transform.lossyScale);
|
||||
float contactOffsetY = (targetRotation * scaledContactPoint).y;
|
||||
float targetHeight = groundPoint.y - contactOffsetY + groundClearance;
|
||||
float nextHeight = Mathf.MoveTowards(
|
||||
currentPosition.y,
|
||||
targetHeight,
|
||||
maximumGroundVerticalSpeed * Time.fixedDeltaTime);
|
||||
DrivePhysicsBody(
|
||||
new Vector3(dragTarget.x, targetHeight, dragTarget.z),
|
||||
targetRotation,
|
||||
movementSpeed,
|
||||
maximumGroundVerticalSpeed);
|
||||
}
|
||||
|
||||
physicsBody.MovePosition(new Vector3(nextPlanarPosition.x, nextHeight, nextPlanarPosition.z));
|
||||
private void DrivePhysicsBody(
|
||||
Vector3 targetPosition,
|
||||
Quaternion targetRotation,
|
||||
float maximumPlanarSpeed,
|
||||
float maximumVerticalSpeed)
|
||||
{
|
||||
Vector3 positionDelta = targetPosition - physicsBody.position;
|
||||
float responseTime = Mathf.Max(positionSmoothTime, 0.01f);
|
||||
Vector3 desiredVelocity = positionDelta / responseTime;
|
||||
Vector3 desiredPlanarVelocity = Vector3.ClampMagnitude(
|
||||
new Vector3(desiredVelocity.x, 0f, desiredVelocity.z),
|
||||
maximumPlanarSpeed);
|
||||
desiredVelocity = new Vector3(
|
||||
desiredPlanarVelocity.x,
|
||||
Mathf.Clamp(desiredVelocity.y, -maximumVerticalSpeed, maximumVerticalSpeed),
|
||||
desiredPlanarVelocity.z);
|
||||
|
||||
physicsBody.MoveRotation(targetRotation);
|
||||
float maximumAcceleration = Mathf.Max(
|
||||
maximumPlanarSpeed,
|
||||
maximumVerticalSpeed) / responseTime;
|
||||
Vector3 velocityChange = Vector3.ClampMagnitude(
|
||||
desiredVelocity - physicsBody.linearVelocity,
|
||||
maximumAcceleration * Time.fixedDeltaTime);
|
||||
physicsBody.AddForce(velocityChange, ForceMode.VelocityChange);
|
||||
|
||||
Quaternion rotationDelta = targetRotation * Quaternion.Inverse(physicsBody.rotation);
|
||||
rotationDelta.ToAngleAxis(out float angle, out Vector3 axis);
|
||||
if (axis.sqrMagnitude < 0.0001f || float.IsNaN(axis.x))
|
||||
return;
|
||||
|
||||
if (angle > 180f)
|
||||
angle -= 360f;
|
||||
|
||||
Vector3 desiredAngularVelocity = axis.normalized *
|
||||
(angle * Mathf.Deg2Rad * rotationFollowSpeed);
|
||||
desiredAngularVelocity = Vector3.ClampMagnitude(
|
||||
desiredAngularVelocity,
|
||||
rotationFollowSpeed);
|
||||
Vector3 angularVelocityChange = Vector3.ClampMagnitude(
|
||||
desiredAngularVelocity - physicsBody.angularVelocity,
|
||||
rotationFollowSpeed * 4f * Time.fixedDeltaTime);
|
||||
physicsBody.AddTorque(angularVelocityChange, ForceMode.VelocityChange);
|
||||
}
|
||||
|
||||
private bool TryGetGroundSurface(
|
||||
@@ -538,8 +607,7 @@ public sealed class NetworkDraggableInteractable : NetworkInteractable, IWorksta
|
||||
Quaternion desiredRotation = Quaternion.LookRotation(
|
||||
surfaceForward.normalized,
|
||||
smoothedGroundNormal) * Quaternion.Euler(rotationOffset);
|
||||
float rotationBlend = 1f - Mathf.Exp(-rotationFollowSpeed * Time.fixedDeltaTime);
|
||||
return Quaternion.Slerp(physicsBody.rotation, desiredRotation, rotationBlend);
|
||||
return desiredRotation;
|
||||
}
|
||||
|
||||
private void CacheGroundContactPoint()
|
||||
@@ -596,19 +664,50 @@ public sealed class NetworkDraggableInteractable : NetworkInteractable, IWorksta
|
||||
return false;
|
||||
}
|
||||
|
||||
private void IgnoreCollisionsWithPlayers()
|
||||
private void RefreshDraggerCollisions()
|
||||
{
|
||||
foreach (CharacterController playerCollider in FindObjectsByType<CharacterController>(
|
||||
FindObjectsInactive.Exclude,
|
||||
FindObjectsSortMode.None))
|
||||
desiredIgnoredColliders.Clear();
|
||||
AddDraggerColliders(firstDraggerClientId.Value);
|
||||
AddDraggerColliders(secondDraggerClientId.Value);
|
||||
|
||||
collidersToRestore.Clear();
|
||||
foreach (Collider ignoredCollider in ignoredPlayerColliders)
|
||||
{
|
||||
foreach (Collider objectCollider in objectColliders)
|
||||
{
|
||||
if (objectCollider != null && playerCollider != null)
|
||||
Physics.IgnoreCollision(objectCollider, playerCollider, true);
|
||||
if (ignoredCollider == null || !desiredIgnoredColliders.Contains(ignoredCollider))
|
||||
collidersToRestore.Add(ignoredCollider);
|
||||
}
|
||||
|
||||
ignoredPlayerColliders.Add(playerCollider);
|
||||
foreach (Collider colliderToRestore in collidersToRestore)
|
||||
{
|
||||
SetCollisionIgnored(colliderToRestore, false);
|
||||
ignoredPlayerColliders.Remove(colliderToRestore);
|
||||
}
|
||||
|
||||
foreach (Collider desiredCollider in desiredIgnoredColliders)
|
||||
{
|
||||
if (desiredCollider != null && ignoredPlayerColliders.Add(desiredCollider))
|
||||
SetCollisionIgnored(desiredCollider, true);
|
||||
}
|
||||
}
|
||||
|
||||
private void AddDraggerColliders(ulong clientId)
|
||||
{
|
||||
if (clientId == NoDragger || !TryGetPlayerObject(clientId, out NetworkObject playerObject))
|
||||
return;
|
||||
|
||||
foreach (Collider playerCollider in playerObject.GetComponentsInChildren<Collider>(true))
|
||||
desiredIgnoredColliders.Add(playerCollider);
|
||||
}
|
||||
|
||||
private void SetCollisionIgnored(Collider playerCollider, bool ignored)
|
||||
{
|
||||
if (playerCollider == null)
|
||||
return;
|
||||
|
||||
foreach (Collider objectCollider in objectColliders)
|
||||
{
|
||||
if (objectCollider != null)
|
||||
Physics.IgnoreCollision(objectCollider, playerCollider, ignored);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -619,13 +718,11 @@ public sealed class NetworkDraggableInteractable : NetworkInteractable, IWorksta
|
||||
if (playerCollider == null)
|
||||
continue;
|
||||
|
||||
foreach (Collider objectCollider in objectColliders)
|
||||
{
|
||||
if (objectCollider != null)
|
||||
Physics.IgnoreCollision(objectCollider, playerCollider, false);
|
||||
}
|
||||
SetCollisionIgnored(playerCollider, false);
|
||||
}
|
||||
|
||||
ignoredPlayerColliders.Clear();
|
||||
desiredIgnoredColliders.Clear();
|
||||
collidersToRestore.Clear();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,6 +18,7 @@ public abstract class NetworkHeldInteractable : NetworkInteractable, IWorkstatio
|
||||
[SerializeField, Min(0.01f)] private float positionSmoothTime = 0.12f;
|
||||
[SerializeField, Min(0.1f)] private float maximumFollowSpeed = 12f;
|
||||
[SerializeField, Min(0.1f)] private float maximumFollowDistance = 1.25f;
|
||||
[SerializeField, Min(0.5f)] private float maximumHoldDistance = 4.5f;
|
||||
[SerializeField, Min(0.1f)] private float rotationFollowSpeed = 14f;
|
||||
|
||||
[Header("Throw")]
|
||||
@@ -35,10 +36,11 @@ public abstract class NetworkHeldInteractable : NetworkInteractable, IWorkstatio
|
||||
NetworkVariableWritePermission.Server);
|
||||
|
||||
private readonly HashSet<Collider> ignoredPlayerColliders = new();
|
||||
private readonly HashSet<Collider> desiredIgnoredColliders = new();
|
||||
private readonly List<Collider> collidersToRestore = new();
|
||||
private float nextCollisionRefreshTime;
|
||||
private Vector3 followVelocity;
|
||||
private Vector3 previousHolderPosition;
|
||||
private bool hasPreviousHolderPosition;
|
||||
private bool initialUseGravity;
|
||||
private CollisionDetectionMode initialCollisionDetectionMode;
|
||||
|
||||
protected abstract Vector3 HoldingOffset { get; }
|
||||
protected abstract string DropPrompt { get; }
|
||||
@@ -68,6 +70,12 @@ public abstract class NetworkHeldInteractable : NetworkInteractable, IWorkstatio
|
||||
|
||||
if (objectColliders == null || objectColliders.Length == 0)
|
||||
objectColliders = GetComponentsInChildren<Collider>(true);
|
||||
|
||||
if (physicsBody != null)
|
||||
{
|
||||
initialUseGravity = physicsBody.useGravity;
|
||||
initialCollisionDetectionMode = physicsBody.collisionDetectionMode;
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnNetworkSpawn()
|
||||
@@ -75,7 +83,7 @@ public abstract class NetworkHeldInteractable : NetworkInteractable, IWorkstatio
|
||||
SpawnedHeldObjects.Add(this);
|
||||
holderClientId.OnValueChanged += HandleHolderChanged;
|
||||
isExternallyControlled.OnValueChanged += HandleExternalControlChanged;
|
||||
ApplyHoldingState(IsHeld || IsExternallyControlled);
|
||||
ApplyHoldingState();
|
||||
}
|
||||
|
||||
public override void OnNetworkDespawn()
|
||||
@@ -83,12 +91,24 @@ public abstract class NetworkHeldInteractable : NetworkInteractable, IWorkstatio
|
||||
holderClientId.OnValueChanged -= HandleHolderChanged;
|
||||
isExternallyControlled.OnValueChanged -= HandleExternalControlChanged;
|
||||
SpawnedHeldObjects.Remove(this);
|
||||
ApplyHoldingState(false);
|
||||
RestorePlayerCollisions();
|
||||
}
|
||||
|
||||
private void LateUpdate()
|
||||
private void Update()
|
||||
{
|
||||
if (!IsSpawned || !IsHeld)
|
||||
if (!IsSpawned || !IsHeld || IsExternallyControlled ||
|
||||
Time.time < nextCollisionRefreshTime)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
nextCollisionRefreshTime = Time.time + collisionRefreshInterval;
|
||||
RefreshHolderCollisions();
|
||||
}
|
||||
|
||||
private void FixedUpdate()
|
||||
{
|
||||
if (!IsServer || !IsSpawned || !IsHeld || IsExternallyControlled || physicsBody == null)
|
||||
return;
|
||||
|
||||
if (!TryGetPlayerObject(holderClientId.Value, out NetworkObject holder))
|
||||
@@ -99,15 +119,10 @@ public abstract class NetworkHeldInteractable : NetworkInteractable, IWorkstatio
|
||||
return;
|
||||
}
|
||||
|
||||
FollowHolderTranslation(holder.transform.position);
|
||||
Transform anchor = ResolveHoldingAnchor(holder);
|
||||
FollowHoldingAnchor(anchor);
|
||||
if (!DriveTowardAnchor(anchor))
|
||||
return;
|
||||
|
||||
if (Time.time >= nextCollisionRefreshTime)
|
||||
{
|
||||
nextCollisionRefreshTime = Time.time + collisionRefreshInterval;
|
||||
IgnoreCollisionsWithPlayers();
|
||||
}
|
||||
}
|
||||
|
||||
public void RequestThrow()
|
||||
@@ -126,7 +141,7 @@ public abstract class NetworkHeldInteractable : NetworkInteractable, IWorkstatio
|
||||
if (IsHeld)
|
||||
holderClientId.Value = NoHolder;
|
||||
|
||||
ApplyHoldingState(true);
|
||||
ApplyHoldingState();
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -136,7 +151,23 @@ public abstract class NetworkHeldInteractable : NetworkInteractable, IWorkstatio
|
||||
return false;
|
||||
|
||||
isExternallyControlled.Value = false;
|
||||
ApplyHoldingState(IsHeld);
|
||||
ApplyHoldingState();
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool TryReleaseExternalControlToPlayer(ulong clientId)
|
||||
{
|
||||
if (!IsServer || !IsSpawned || !IsExternallyControlled ||
|
||||
TryGetHeldObject(clientId, out _) ||
|
||||
NetworkHandItemInteractable.TryGetHeldItem(clientId, out _) ||
|
||||
!TryGetPlayerObject(clientId, out _))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
isExternallyControlled.Value = false;
|
||||
holderClientId.Value = clientId;
|
||||
ApplyHoldingState();
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -208,13 +239,13 @@ public abstract class NetworkHeldInteractable : NetworkInteractable, IWorkstatio
|
||||
return;
|
||||
|
||||
holderClientId.Value = clientId;
|
||||
ApplyHoldingState(true);
|
||||
ApplyHoldingState();
|
||||
}
|
||||
|
||||
private void StopHolding()
|
||||
{
|
||||
holderClientId.Value = NoHolder;
|
||||
ApplyHoldingState(IsExternallyControlled);
|
||||
ApplyHoldingState();
|
||||
}
|
||||
|
||||
private Transform ResolveHoldingAnchor(NetworkObject holder)
|
||||
@@ -224,94 +255,134 @@ public abstract class NetworkHeldInteractable : NetworkInteractable, IWorkstatio
|
||||
return cameraController != null ? cameraController.AimTransform : holder.transform;
|
||||
}
|
||||
|
||||
private void FollowHoldingAnchor(Transform anchor)
|
||||
private bool DriveTowardAnchor(Transform anchor)
|
||||
{
|
||||
Vector3 targetPosition = anchor.TransformPoint(HoldingOffset);
|
||||
Vector3 targetDelta = targetPosition - transform.position;
|
||||
Vector3 targetDelta = targetPosition - physicsBody.position;
|
||||
|
||||
if (targetDelta.sqrMagnitude > maximumFollowDistance * maximumFollowDistance)
|
||||
if (targetDelta.sqrMagnitude > maximumHoldDistance * maximumHoldDistance)
|
||||
{
|
||||
transform.position = targetPosition -
|
||||
targetDelta.normalized * maximumFollowDistance;
|
||||
followVelocity = Vector3.zero;
|
||||
StopHolding();
|
||||
return false;
|
||||
}
|
||||
|
||||
transform.position = Vector3.SmoothDamp(
|
||||
transform.position,
|
||||
targetPosition,
|
||||
ref followVelocity,
|
||||
positionSmoothTime,
|
||||
maximumFollowSpeed,
|
||||
Time.deltaTime);
|
||||
float distance = targetDelta.magnitude;
|
||||
float speedDistance = Mathf.Max(maximumFollowDistance, 0.01f);
|
||||
float desiredSpeed = maximumFollowSpeed * Mathf.Clamp01(distance / speedDistance);
|
||||
Vector3 desiredVelocity = distance > 0.0001f
|
||||
? targetDelta / distance * desiredSpeed
|
||||
: Vector3.zero;
|
||||
float maximumAcceleration = maximumFollowSpeed / Mathf.Max(positionSmoothTime, 0.01f);
|
||||
Vector3 velocityChange = Vector3.ClampMagnitude(
|
||||
desiredVelocity - physicsBody.linearVelocity,
|
||||
maximumAcceleration * Time.fixedDeltaTime);
|
||||
physicsBody.AddForce(velocityChange, ForceMode.VelocityChange);
|
||||
|
||||
float rotationBlend = 1f - Mathf.Exp(-rotationFollowSpeed * Time.deltaTime);
|
||||
transform.rotation = Quaternion.Slerp(
|
||||
transform.rotation,
|
||||
anchor.rotation,
|
||||
rotationBlend);
|
||||
DriveRotation(anchor.rotation);
|
||||
return true;
|
||||
}
|
||||
|
||||
private void FollowHolderTranslation(Vector3 holderPosition)
|
||||
private void DriveRotation(Quaternion targetRotation)
|
||||
{
|
||||
if (!hasPreviousHolderPosition)
|
||||
{
|
||||
previousHolderPosition = holderPosition;
|
||||
hasPreviousHolderPosition = true;
|
||||
Quaternion rotationDelta = targetRotation * Quaternion.Inverse(physicsBody.rotation);
|
||||
rotationDelta.ToAngleAxis(out float angle, out Vector3 axis);
|
||||
if (axis.sqrMagnitude < 0.0001f || float.IsNaN(axis.x))
|
||||
return;
|
||||
|
||||
if (angle > 180f)
|
||||
angle -= 360f;
|
||||
|
||||
Vector3 desiredAngularVelocity = axis.normalized *
|
||||
(angle * Mathf.Deg2Rad * rotationFollowSpeed);
|
||||
desiredAngularVelocity = Vector3.ClampMagnitude(
|
||||
desiredAngularVelocity,
|
||||
rotationFollowSpeed);
|
||||
Vector3 angularVelocityChange = Vector3.ClampMagnitude(
|
||||
desiredAngularVelocity - physicsBody.angularVelocity,
|
||||
rotationFollowSpeed * 4f * Time.fixedDeltaTime);
|
||||
physicsBody.AddTorque(angularVelocityChange, ForceMode.VelocityChange);
|
||||
}
|
||||
|
||||
Vector3 holderDelta = holderPosition - previousHolderPosition;
|
||||
previousHolderPosition = holderPosition;
|
||||
private void HandleHolderChanged(ulong _, ulong __) => ApplyHoldingState();
|
||||
|
||||
transform.position += holderDelta;
|
||||
}
|
||||
private void HandleExternalControlChanged(bool _, bool __) => ApplyHoldingState();
|
||||
|
||||
private void HandleHolderChanged(ulong _, ulong currentHolder) =>
|
||||
ApplyHoldingState(currentHolder != NoHolder || IsExternallyControlled);
|
||||
|
||||
private void HandleExternalControlChanged(bool _, bool isControlled) =>
|
||||
ApplyHoldingState(IsHeld || isControlled);
|
||||
|
||||
private void ApplyHoldingState(bool isHeld)
|
||||
private void ApplyHoldingState()
|
||||
{
|
||||
followVelocity = Vector3.zero;
|
||||
hasPreviousHolderPosition = false;
|
||||
|
||||
if (physicsBody != null)
|
||||
{
|
||||
bool shouldBeKinematic = isHeld || !IsServer;
|
||||
bool isPhysicallyHeld = IsHeld && !IsExternallyControlled;
|
||||
bool shouldBeKinematic = IsExternallyControlled || !IsServer;
|
||||
|
||||
if (physicsBody.isKinematic && !shouldBeKinematic)
|
||||
if (shouldBeKinematic)
|
||||
{
|
||||
physicsBody.collisionDetectionMode = CollisionDetectionMode.ContinuousSpeculative;
|
||||
physicsBody.isKinematic = true;
|
||||
physicsBody.useGravity = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
physicsBody.isKinematic = false;
|
||||
physicsBody.useGravity = isPhysicallyHeld ? false : initialUseGravity;
|
||||
physicsBody.collisionDetectionMode = ResolveDynamicCollisionDetectionMode();
|
||||
}
|
||||
|
||||
if (!physicsBody.isKinematic)
|
||||
if (!isPhysicallyHeld)
|
||||
{
|
||||
physicsBody.linearVelocity = Vector3.zero;
|
||||
physicsBody.angularVelocity = Vector3.zero;
|
||||
}
|
||||
|
||||
physicsBody.isKinematic = shouldBeKinematic;
|
||||
}
|
||||
|
||||
if (isHeld)
|
||||
IgnoreCollisionsWithPlayers();
|
||||
if (IsHeld && !IsExternallyControlled)
|
||||
RefreshHolderCollisions();
|
||||
else
|
||||
RestorePlayerCollisions();
|
||||
}
|
||||
|
||||
private void IgnoreCollisionsWithPlayers()
|
||||
private CollisionDetectionMode ResolveDynamicCollisionDetectionMode() =>
|
||||
initialCollisionDetectionMode == CollisionDetectionMode.Discrete
|
||||
? CollisionDetectionMode.ContinuousDynamic
|
||||
: initialCollisionDetectionMode;
|
||||
|
||||
private void RefreshHolderCollisions()
|
||||
{
|
||||
foreach (CharacterController playerCollider in FindObjectsByType<CharacterController>(
|
||||
FindObjectsInactive.Exclude,
|
||||
FindObjectsSortMode.None))
|
||||
desiredIgnoredColliders.Clear();
|
||||
if (TryGetPlayerObject(holderClientId.Value, out NetworkObject holder))
|
||||
{
|
||||
foreach (Collider objectCollider in objectColliders)
|
||||
{
|
||||
if (objectCollider != null && playerCollider != null)
|
||||
Physics.IgnoreCollision(objectCollider, playerCollider, true);
|
||||
foreach (Collider holderCollider in holder.GetComponentsInChildren<Collider>(true))
|
||||
desiredIgnoredColliders.Add(holderCollider);
|
||||
}
|
||||
|
||||
ignoredPlayerColliders.Add(playerCollider);
|
||||
collidersToRestore.Clear();
|
||||
foreach (Collider ignoredCollider in ignoredPlayerColliders)
|
||||
{
|
||||
if (ignoredCollider == null || !desiredIgnoredColliders.Contains(ignoredCollider))
|
||||
collidersToRestore.Add(ignoredCollider);
|
||||
}
|
||||
|
||||
foreach (Collider colliderToRestore in collidersToRestore)
|
||||
{
|
||||
SetCollisionIgnored(colliderToRestore, false);
|
||||
ignoredPlayerColliders.Remove(colliderToRestore);
|
||||
}
|
||||
|
||||
foreach (Collider desiredCollider in desiredIgnoredColliders)
|
||||
{
|
||||
if (desiredCollider != null && ignoredPlayerColliders.Add(desiredCollider))
|
||||
SetCollisionIgnored(desiredCollider, true);
|
||||
}
|
||||
}
|
||||
|
||||
private void SetCollisionIgnored(Collider playerCollider, bool ignored)
|
||||
{
|
||||
if (playerCollider == null)
|
||||
return;
|
||||
|
||||
foreach (Collider objectCollider in objectColliders)
|
||||
{
|
||||
if (objectCollider != null)
|
||||
Physics.IgnoreCollision(objectCollider, playerCollider, ignored);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -322,13 +393,11 @@ public abstract class NetworkHeldInteractable : NetworkInteractable, IWorkstatio
|
||||
if (playerCollider == null)
|
||||
continue;
|
||||
|
||||
foreach (Collider objectCollider in objectColliders)
|
||||
{
|
||||
if (objectCollider != null)
|
||||
Physics.IgnoreCollision(objectCollider, playerCollider, false);
|
||||
}
|
||||
SetCollisionIgnored(playerCollider, false);
|
||||
}
|
||||
|
||||
ignoredPlayerColliders.Clear();
|
||||
desiredIgnoredColliders.Clear();
|
||||
collidersToRestore.Clear();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,31 @@
|
||||
using UnityEngine;
|
||||
|
||||
public interface IWorkstationItemControl
|
||||
{
|
||||
bool TryAcquireExternalControl();
|
||||
bool TryReleaseExternalControl();
|
||||
bool TryReleaseExternalControlToPlayer(ulong clientId);
|
||||
}
|
||||
|
||||
public static class WorkstationItemControlUtility
|
||||
{
|
||||
public static bool TryGetControl(
|
||||
NetworkItem item,
|
||||
out IWorkstationItemControl itemControl)
|
||||
{
|
||||
if (item != null)
|
||||
{
|
||||
foreach (MonoBehaviour component in item.GetComponents<MonoBehaviour>())
|
||||
{
|
||||
if (component is IWorkstationItemControl candidate)
|
||||
{
|
||||
itemControl = candidate;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
itemControl = null;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,11 +16,13 @@ public sealed class ItemDefinition : ScriptableObject
|
||||
[SerializeField] private string itemId;
|
||||
[SerializeField] private string displayName;
|
||||
[SerializeField] private ItemCategory category;
|
||||
[SerializeField] private bool isAssemblyReady;
|
||||
[SerializeField] private NetworkObject worldPrefab;
|
||||
|
||||
public string ItemId => itemId;
|
||||
public string DisplayName => string.IsNullOrWhiteSpace(displayName) ? name : displayName;
|
||||
public ItemCategory Category => category;
|
||||
public bool IsAssemblyReady => isAssemblyReady;
|
||||
public NetworkObject WorldPrefab => worldPrefab;
|
||||
|
||||
private void OnValidate()
|
||||
|
||||
@@ -10,6 +10,7 @@ public sealed class PlayerInteractionController : NetworkBehaviour, IPlayerSyste
|
||||
private Camera playerCamera;
|
||||
private IInteractable focusedInteractable;
|
||||
private IPlayerInteractionSession activeSession;
|
||||
private readonly RaycastHit[] interactionHits = new RaycastHit[32];
|
||||
private bool activeSessionReleaseRequested;
|
||||
private bool isInitialized;
|
||||
|
||||
@@ -54,10 +55,57 @@ public sealed class PlayerInteractionController : NetworkBehaviour, IPlayerSyste
|
||||
private IInteractable FindFocusedInteractable()
|
||||
{
|
||||
Ray ray = new(playerCamera.transform.position, playerCamera.transform.forward);
|
||||
if (!Physics.Raycast(ray, out RaycastHit hit, interactionDistance, interactionMask, QueryTriggerInteraction.Collide))
|
||||
int hitCount = Physics.RaycastNonAlloc(
|
||||
ray,
|
||||
interactionHits,
|
||||
interactionDistance,
|
||||
interactionMask,
|
||||
QueryTriggerInteraction.Collide);
|
||||
if (hitCount <= 0)
|
||||
return null;
|
||||
|
||||
foreach (MonoBehaviour component in hit.collider.GetComponentsInParent<MonoBehaviour>())
|
||||
IInteractable closestAvailable = null;
|
||||
float closestAvailableDistance = float.PositiveInfinity;
|
||||
IInteractable closestUnavailable = null;
|
||||
float closestUnavailableDistance = float.PositiveInfinity;
|
||||
float closestBlockingDistance = float.PositiveInfinity;
|
||||
|
||||
for (int hitIndex = 0; hitIndex < hitCount; hitIndex++)
|
||||
{
|
||||
RaycastHit hit = interactionHits[hitIndex];
|
||||
IInteractable interactable = FindInteractable(hit.collider);
|
||||
if (interactable == null)
|
||||
{
|
||||
closestBlockingDistance = Mathf.Min(closestBlockingDistance, hit.distance);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (interactable.IsInteractionAvailable)
|
||||
{
|
||||
if (hit.distance < closestAvailableDistance)
|
||||
{
|
||||
closestAvailable = interactable;
|
||||
closestAvailableDistance = hit.distance;
|
||||
}
|
||||
}
|
||||
else if (hit.distance < closestUnavailableDistance)
|
||||
{
|
||||
closestUnavailable = interactable;
|
||||
closestUnavailableDistance = hit.distance;
|
||||
}
|
||||
}
|
||||
|
||||
if (closestAvailable != null && closestAvailableDistance <= closestBlockingDistance)
|
||||
return closestAvailable;
|
||||
|
||||
return closestUnavailable != null && closestUnavailableDistance <= closestBlockingDistance
|
||||
? closestUnavailable
|
||||
: null;
|
||||
}
|
||||
|
||||
private static IInteractable FindInteractable(Collider collider)
|
||||
{
|
||||
foreach (MonoBehaviour component in collider.GetComponentsInParent<MonoBehaviour>())
|
||||
{
|
||||
if (component is IInteractable interactable)
|
||||
return interactable;
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e48d638d2d22411db1b67c8276c6f6c9
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
+609
@@ -0,0 +1,609 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Unity.Netcode;
|
||||
using UnityEngine;
|
||||
|
||||
public enum RocketAssemblyWorkstationState : byte
|
||||
{
|
||||
Loading,
|
||||
Assembling,
|
||||
OutputReady
|
||||
}
|
||||
|
||||
public sealed class NetworkRocketAssemblyWorkstation : NetworkWorkstationController
|
||||
{
|
||||
public const int MaximumSlotCount = 9;
|
||||
private const ulong EmptySlot = ulong.MaxValue;
|
||||
|
||||
[Header("Recipes")]
|
||||
[SerializeField] private List<RocketAssemblyRecipe> recipes = new();
|
||||
|
||||
[Header("Slots (bottom to top)")]
|
||||
[Tooltip("Element 0 is the lowest physical slot. Only the first 9 entries are used.")]
|
||||
[SerializeField] private List<RocketAssemblyInputSlot> slotsBottomToTop = new();
|
||||
|
||||
[Header("Output")]
|
||||
[SerializeField] private Transform outputPoint;
|
||||
[SerializeField, Min(0.1f)] private float outputReleaseDistance = 1.5f;
|
||||
|
||||
[Header("Interaction")]
|
||||
[SerializeField, Min(0.1f)] private float maximumTakeDistance = 3.5f;
|
||||
[SerializeField, Min(0.05f)] private float reinsertCooldownAfterTake = 0.5f;
|
||||
|
||||
private readonly NetworkVariable<RocketAssemblyWorkstationState> state = new(
|
||||
RocketAssemblyWorkstationState.Loading,
|
||||
NetworkVariableReadPermission.Everyone,
|
||||
NetworkVariableWritePermission.Server);
|
||||
|
||||
private readonly NetworkVariable<int> selectedRecipeIndex = new(
|
||||
-1,
|
||||
NetworkVariableReadPermission.Everyone,
|
||||
NetworkVariableWritePermission.Server);
|
||||
|
||||
private readonly NetworkVariable<double> assemblyStartedAt = new(
|
||||
0d,
|
||||
NetworkVariableReadPermission.Everyone,
|
||||
NetworkVariableWritePermission.Server);
|
||||
|
||||
private readonly NetworkVariable<double> assemblyEndsAt = new(
|
||||
0d,
|
||||
NetworkVariableReadPermission.Everyone,
|
||||
NetworkVariableWritePermission.Server);
|
||||
|
||||
private readonly NetworkVariable<bool> assemblyWillBeDefective = new(
|
||||
false,
|
||||
NetworkVariableReadPermission.Everyone,
|
||||
NetworkVariableWritePermission.Server);
|
||||
|
||||
private readonly NetworkList<ulong> slotItemNetworkObjectIds = new(
|
||||
default,
|
||||
NetworkVariableReadPermission.Everyone,
|
||||
NetworkVariableWritePermission.Server);
|
||||
|
||||
private readonly NetworkItem[] slottedItems = new NetworkItem[MaximumSlotCount];
|
||||
private readonly IWorkstationItemControl[] slottedItemControls =
|
||||
new IWorkstationItemControl[MaximumSlotCount];
|
||||
private readonly Dictionary<ulong, double> reinsertBlockedUntil = new();
|
||||
|
||||
private NetworkItem currentOutput;
|
||||
|
||||
public override bool IsOperating => State == RocketAssemblyWorkstationState.Assembling;
|
||||
public RocketAssemblyWorkstationState State => state.Value;
|
||||
public IReadOnlyList<RocketAssemblyRecipe> Recipes => recipes;
|
||||
public IReadOnlyList<NetworkItem> SlottedItems => slottedItems;
|
||||
public int SlotCount => Mathf.Min(slotsBottomToTop.Count, MaximumSlotCount);
|
||||
public int SelectedRecipeIndex => selectedRecipeIndex.Value;
|
||||
public RocketAssemblyRecipe SelectedRecipe => TryGetRecipe(
|
||||
selectedRecipeIndex.Value,
|
||||
out RocketAssemblyRecipe recipe)
|
||||
? recipe
|
||||
: null;
|
||||
public bool AssemblyWillBeDefective => assemblyWillBeDefective.Value;
|
||||
public bool LastCompletedAssemblyWasDefective =>
|
||||
State == RocketAssemblyWorkstationState.OutputReady &&
|
||||
assemblyWillBeDefective.Value;
|
||||
public NetworkItem CurrentOutput => currentOutput;
|
||||
|
||||
public int OccupiedSlotCount
|
||||
{
|
||||
get
|
||||
{
|
||||
int count = 0;
|
||||
int synchronizedSlotCount = Mathf.Min(slotItemNetworkObjectIds.Count, SlotCount);
|
||||
for (int index = 0; index < synchronizedSlotCount; index++)
|
||||
{
|
||||
if (slotItemNetworkObjectIds[index] != EmptySlot)
|
||||
count++;
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
}
|
||||
|
||||
public bool CanStartAssembly =>
|
||||
State == RocketAssemblyWorkstationState.Loading &&
|
||||
SelectedRecipe != null &&
|
||||
OccupiedSlotCount >= SelectedRecipe.RequiredPartCount;
|
||||
|
||||
public float AssemblyProgress
|
||||
{
|
||||
get
|
||||
{
|
||||
if (State == RocketAssemblyWorkstationState.OutputReady)
|
||||
return 1f;
|
||||
|
||||
if (!IsOperating)
|
||||
return 0f;
|
||||
|
||||
double duration = assemblyEndsAt.Value - assemblyStartedAt.Value;
|
||||
return duration <= 0d
|
||||
? 1f
|
||||
: Mathf.Clamp01((float)((GetNetworkTime() - assemblyStartedAt.Value) / duration));
|
||||
}
|
||||
}
|
||||
|
||||
public float RemainingSeconds => !IsOperating
|
||||
? 0f
|
||||
: Mathf.Max(0f, (float)(assemblyEndsAt.Value - GetNetworkTime()));
|
||||
|
||||
public event Action Changed;
|
||||
|
||||
private void Awake() => ConfigureSlots();
|
||||
|
||||
private void OnValidate()
|
||||
{
|
||||
if (slotsBottomToTop.Count > MaximumSlotCount)
|
||||
slotsBottomToTop.RemoveRange(
|
||||
MaximumSlotCount,
|
||||
slotsBottomToTop.Count - MaximumSlotCount);
|
||||
|
||||
ConfigureSlots();
|
||||
}
|
||||
|
||||
public override void OnNetworkSpawn()
|
||||
{
|
||||
state.OnValueChanged += HandleStateChanged;
|
||||
selectedRecipeIndex.OnValueChanged += HandleSelectedRecipeChanged;
|
||||
assemblyStartedAt.OnValueChanged += HandleAssemblyTimeChanged;
|
||||
assemblyEndsAt.OnValueChanged += HandleAssemblyTimeChanged;
|
||||
assemblyWillBeDefective.OnValueChanged += HandleDefectiveStateChanged;
|
||||
slotItemNetworkObjectIds.OnListChanged += HandleSlotListChanged;
|
||||
|
||||
if (IsServer)
|
||||
InitializeOnServer();
|
||||
|
||||
Changed?.Invoke();
|
||||
}
|
||||
|
||||
public override void OnNetworkDespawn()
|
||||
{
|
||||
state.OnValueChanged -= HandleStateChanged;
|
||||
selectedRecipeIndex.OnValueChanged -= HandleSelectedRecipeChanged;
|
||||
assemblyStartedAt.OnValueChanged -= HandleAssemblyTimeChanged;
|
||||
assemblyEndsAt.OnValueChanged -= HandleAssemblyTimeChanged;
|
||||
assemblyWillBeDefective.OnValueChanged -= HandleDefectiveStateChanged;
|
||||
slotItemNetworkObjectIds.OnListChanged -= HandleSlotListChanged;
|
||||
}
|
||||
|
||||
private void Update()
|
||||
{
|
||||
if (!IsServer || !IsSpawned)
|
||||
return;
|
||||
|
||||
RemoveMissingSlottedItems();
|
||||
|
||||
if (State == RocketAssemblyWorkstationState.Assembling &&
|
||||
GetNetworkTime() >= assemblyEndsAt.Value)
|
||||
{
|
||||
CompleteAssemblyOnServer();
|
||||
}
|
||||
else if (State == RocketAssemblyWorkstationState.OutputReady &&
|
||||
HasOutputLeftWorkstation())
|
||||
{
|
||||
ResetToLoadingOnServer();
|
||||
}
|
||||
}
|
||||
|
||||
private void LateUpdate()
|
||||
{
|
||||
if (!IsServer || !IsSpawned ||
|
||||
State == RocketAssemblyWorkstationState.OutputReady)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
for (int index = 0; index < SlotCount; index++)
|
||||
{
|
||||
if (slottedItems[index] != null)
|
||||
SnapToSlot(index, slottedItems[index].transform);
|
||||
}
|
||||
}
|
||||
|
||||
public bool TryInsertItem(int slotIndex, NetworkItem item)
|
||||
{
|
||||
if (!IsServer || !IsSpawned ||
|
||||
State != RocketAssemblyWorkstationState.Loading ||
|
||||
!IsValidSlotIndex(slotIndex) ||
|
||||
slottedItems[slotIndex] != null ||
|
||||
!IsReadyRocketPart(item) ||
|
||||
IsTemporarilyBlockedFromReinsert(item) ||
|
||||
IsAlreadySlotted(item) ||
|
||||
!WorkstationItemControlUtility.TryGetControl(
|
||||
item,
|
||||
out IWorkstationItemControl itemControl) ||
|
||||
!itemControl.TryAcquireExternalControl())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
slottedItems[slotIndex] = item;
|
||||
slottedItemControls[slotIndex] = itemControl;
|
||||
slotItemNetworkObjectIds[slotIndex] = item.NetworkObjectId;
|
||||
SnapToSlot(slotIndex, item.transform);
|
||||
Changed?.Invoke();
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool CanTakeSlotItem(int slotIndex) =>
|
||||
IsSpawned &&
|
||||
State == RocketAssemblyWorkstationState.Loading &&
|
||||
IsValidSlotIndex(slotIndex) &&
|
||||
slotIndex < slotItemNetworkObjectIds.Count &&
|
||||
slotItemNetworkObjectIds[slotIndex] != EmptySlot;
|
||||
|
||||
public string GetTakePrompt(int slotIndex)
|
||||
{
|
||||
if (!CanTakeSlotItem(slotIndex))
|
||||
return "Take part";
|
||||
|
||||
NetworkItem item = IsServer ? slottedItems[slotIndex] : ResolveSynchronizedItem(slotIndex);
|
||||
return item != null ? $"Take {item.DisplayName}" : "Take part";
|
||||
}
|
||||
|
||||
public void RequestTakeSlotItem(int slotIndex)
|
||||
{
|
||||
if (!CanTakeSlotItem(slotIndex))
|
||||
return;
|
||||
|
||||
RequestTakeSlotItemServerRpc(slotIndex);
|
||||
}
|
||||
|
||||
public void RequestSelectRecipe(int recipeIndex)
|
||||
{
|
||||
if (!IsSpawned)
|
||||
return;
|
||||
|
||||
if (IsServer)
|
||||
SelectRecipeOnServer(recipeIndex);
|
||||
else
|
||||
RequestSelectRecipeServerRpc(recipeIndex);
|
||||
}
|
||||
|
||||
public void RequestStartAssembly()
|
||||
{
|
||||
if (!IsSpawned)
|
||||
return;
|
||||
|
||||
if (IsServer)
|
||||
TryStartAssemblyOnServer();
|
||||
else
|
||||
RequestStartAssemblyServerRpc();
|
||||
}
|
||||
|
||||
public void SetAssemblyRequested(bool isActivated)
|
||||
{
|
||||
if (isActivated && IsServer && IsSpawned)
|
||||
TryStartAssemblyOnServer();
|
||||
}
|
||||
|
||||
[ContextMenu("Debug/Start Assembly (Server Play Mode)")]
|
||||
private void StartAssemblyFromContextMenu()
|
||||
{
|
||||
if (Application.isPlaying && IsServer && IsSpawned)
|
||||
TryStartAssemblyOnServer();
|
||||
}
|
||||
|
||||
[Rpc(SendTo.Server, InvokePermission = RpcInvokePermission.Everyone)]
|
||||
private void RequestTakeSlotItemServerRpc(
|
||||
int slotIndex,
|
||||
RpcParams rpcParams = default)
|
||||
{
|
||||
if (!CanTakeSlotItem(slotIndex) ||
|
||||
!TryGetPlayerObject(rpcParams.Receive.SenderClientId, out NetworkObject playerObject))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
float maximumDistanceSquared = maximumTakeDistance * maximumTakeDistance;
|
||||
if ((playerObject.transform.position -
|
||||
slotsBottomToTop[slotIndex].InteractionPosition).sqrMagnitude > maximumDistanceSquared)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
IWorkstationItemControl itemControl = slottedItemControls[slotIndex];
|
||||
if (itemControl == null ||
|
||||
!itemControl.TryReleaseExternalControlToPlayer(rpcParams.Receive.SenderClientId))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
NetworkItem item = slottedItems[slotIndex];
|
||||
if (item != null)
|
||||
{
|
||||
reinsertBlockedUntil[item.NetworkObjectId] =
|
||||
GetNetworkTime() + reinsertCooldownAfterTake;
|
||||
}
|
||||
|
||||
ClearSlot(slotIndex);
|
||||
}
|
||||
|
||||
[Rpc(SendTo.Server, InvokePermission = RpcInvokePermission.Everyone)]
|
||||
private void RequestSelectRecipeServerRpc(int recipeIndex) =>
|
||||
SelectRecipeOnServer(recipeIndex);
|
||||
|
||||
[Rpc(SendTo.Server, InvokePermission = RpcInvokePermission.Everyone)]
|
||||
private void RequestStartAssemblyServerRpc() => TryStartAssemblyOnServer();
|
||||
|
||||
private void InitializeOnServer()
|
||||
{
|
||||
slotItemNetworkObjectIds.Clear();
|
||||
for (int index = 0; index < SlotCount; index++)
|
||||
slotItemNetworkObjectIds.Add(EmptySlot);
|
||||
|
||||
Array.Clear(slottedItems, 0, slottedItems.Length);
|
||||
Array.Clear(slottedItemControls, 0, slottedItemControls.Length);
|
||||
reinsertBlockedUntil.Clear();
|
||||
currentOutput = null;
|
||||
selectedRecipeIndex.Value = FindFirstValidRecipeIndex();
|
||||
assemblyStartedAt.Value = 0d;
|
||||
assemblyEndsAt.Value = 0d;
|
||||
assemblyWillBeDefective.Value = false;
|
||||
state.Value = RocketAssemblyWorkstationState.Loading;
|
||||
}
|
||||
|
||||
private void SelectRecipeOnServer(int recipeIndex)
|
||||
{
|
||||
if (!IsServer || !IsSpawned ||
|
||||
State != RocketAssemblyWorkstationState.Loading ||
|
||||
!TryGetRecipe(recipeIndex, out _))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
selectedRecipeIndex.Value = recipeIndex;
|
||||
Changed?.Invoke();
|
||||
}
|
||||
|
||||
private bool TryStartAssemblyOnServer()
|
||||
{
|
||||
RocketAssemblyRecipe recipe = SelectedRecipe;
|
||||
if (!IsServer || !IsSpawned || !CanStartAssembly || recipe == null)
|
||||
return false;
|
||||
|
||||
assemblyWillBeDefective.Value = !recipe.Matches(slottedItems);
|
||||
double now = GetNetworkTime();
|
||||
assemblyStartedAt.Value = now;
|
||||
assemblyEndsAt.Value = now + recipe.AssemblyDuration;
|
||||
state.Value = RocketAssemblyWorkstationState.Assembling;
|
||||
Changed?.Invoke();
|
||||
return true;
|
||||
}
|
||||
|
||||
private void CompleteAssemblyOnServer()
|
||||
{
|
||||
RocketAssemblyRecipe recipe = SelectedRecipe;
|
||||
if (recipe == null)
|
||||
{
|
||||
CancelAssemblyOnServer();
|
||||
return;
|
||||
}
|
||||
|
||||
bool defective = assemblyWillBeDefective.Value;
|
||||
ItemDefinition outputDefinition = defective
|
||||
? recipe.DefectiveOutputItem
|
||||
: recipe.OutputItem;
|
||||
if (outputDefinition == null || outputDefinition.WorldPrefab == null)
|
||||
{
|
||||
CancelAssemblyOnServer();
|
||||
return;
|
||||
}
|
||||
|
||||
for (int index = 0; index < SlotCount; index++)
|
||||
{
|
||||
NetworkItem item = slottedItems[index];
|
||||
ClearSlotRuntime(index);
|
||||
|
||||
if (item != null && item.NetworkObject != null && item.IsSpawned)
|
||||
item.NetworkObject.Despawn(true);
|
||||
|
||||
slotItemNetworkObjectIds[index] = EmptySlot;
|
||||
}
|
||||
|
||||
Transform spawnPoint = outputPoint != null ? outputPoint : transform;
|
||||
NetworkObject outputObject = Instantiate(
|
||||
outputDefinition.WorldPrefab,
|
||||
spawnPoint.position,
|
||||
spawnPoint.rotation);
|
||||
outputObject.Spawn();
|
||||
|
||||
currentOutput = outputObject.GetComponent<NetworkItem>();
|
||||
if (currentOutput == null ||
|
||||
!WorkstationItemControlUtility.TryGetControl(currentOutput, out _))
|
||||
{
|
||||
Debug.LogError(
|
||||
$"{name} cannot produce '{outputDefinition.DisplayName}': the output prefab " +
|
||||
"must contain NetworkItem and a supported Carry or Drag interaction component.",
|
||||
this);
|
||||
outputObject.Despawn(true);
|
||||
currentOutput = null;
|
||||
ResetToLoadingOnServer();
|
||||
return;
|
||||
}
|
||||
|
||||
assemblyStartedAt.Value = 0d;
|
||||
assemblyEndsAt.Value = 0d;
|
||||
state.Value = RocketAssemblyWorkstationState.OutputReady;
|
||||
Changed?.Invoke();
|
||||
}
|
||||
|
||||
private void CancelAssemblyOnServer()
|
||||
{
|
||||
assemblyStartedAt.Value = 0d;
|
||||
assemblyEndsAt.Value = 0d;
|
||||
assemblyWillBeDefective.Value = false;
|
||||
state.Value = RocketAssemblyWorkstationState.Loading;
|
||||
Changed?.Invoke();
|
||||
}
|
||||
|
||||
private void ResetToLoadingOnServer()
|
||||
{
|
||||
currentOutput = null;
|
||||
assemblyStartedAt.Value = 0d;
|
||||
assemblyEndsAt.Value = 0d;
|
||||
assemblyWillBeDefective.Value = false;
|
||||
state.Value = RocketAssemblyWorkstationState.Loading;
|
||||
Changed?.Invoke();
|
||||
}
|
||||
|
||||
private void RemoveMissingSlottedItems()
|
||||
{
|
||||
if (State == RocketAssemblyWorkstationState.Assembling)
|
||||
{
|
||||
for (int index = 0; index < SlotCount; index++)
|
||||
{
|
||||
if (slotItemNetworkObjectIds[index] != EmptySlot &&
|
||||
(slottedItems[index] == null || !slottedItems[index].IsSpawned))
|
||||
{
|
||||
CancelAssemblyOnServer();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (int index = 0; index < SlotCount; index++)
|
||||
{
|
||||
if (slotItemNetworkObjectIds[index] != EmptySlot &&
|
||||
(slottedItems[index] == null || !slottedItems[index].IsSpawned))
|
||||
{
|
||||
ClearSlot(index);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private bool HasOutputLeftWorkstation()
|
||||
{
|
||||
if (currentOutput == null || !currentOutput.IsSpawned)
|
||||
return true;
|
||||
|
||||
Transform spawnPoint = outputPoint != null ? outputPoint : transform;
|
||||
return (currentOutput.transform.position - spawnPoint.position).sqrMagnitude >
|
||||
outputReleaseDistance * outputReleaseDistance;
|
||||
}
|
||||
|
||||
private void ClearSlot(int slotIndex)
|
||||
{
|
||||
ClearSlotRuntime(slotIndex);
|
||||
slotItemNetworkObjectIds[slotIndex] = EmptySlot;
|
||||
Changed?.Invoke();
|
||||
}
|
||||
|
||||
private void ClearSlotRuntime(int slotIndex)
|
||||
{
|
||||
slottedItems[slotIndex] = null;
|
||||
slottedItemControls[slotIndex] = null;
|
||||
}
|
||||
|
||||
private void SnapToSlot(int slotIndex, Transform itemTransform)
|
||||
{
|
||||
Transform snapPoint = slotsBottomToTop[slotIndex].SnapPoint;
|
||||
itemTransform.SetPositionAndRotation(snapPoint.position, snapPoint.rotation);
|
||||
}
|
||||
|
||||
private bool IsAlreadySlotted(NetworkItem item)
|
||||
{
|
||||
for (int index = 0; index < SlotCount; index++)
|
||||
{
|
||||
if (slottedItems[index] == item)
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private bool IsTemporarilyBlockedFromReinsert(NetworkItem item)
|
||||
{
|
||||
if (item == null ||
|
||||
!reinsertBlockedUntil.TryGetValue(item.NetworkObjectId, out double blockedUntil))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (GetNetworkTime() < blockedUntil)
|
||||
return true;
|
||||
|
||||
reinsertBlockedUntil.Remove(item.NetworkObjectId);
|
||||
return false;
|
||||
}
|
||||
|
||||
private NetworkItem ResolveSynchronizedItem(int slotIndex)
|
||||
{
|
||||
if (!IsValidSlotIndex(slotIndex) ||
|
||||
slotIndex >= slotItemNetworkObjectIds.Count ||
|
||||
slotItemNetworkObjectIds[slotIndex] == EmptySlot ||
|
||||
NetworkManager == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return NetworkManager.SpawnManager.SpawnedObjects.TryGetValue(
|
||||
slotItemNetworkObjectIds[slotIndex],
|
||||
out NetworkObject networkObject)
|
||||
? networkObject.GetComponent<NetworkItem>()
|
||||
: null;
|
||||
}
|
||||
|
||||
private bool TryGetPlayerObject(ulong clientId, out NetworkObject playerObject)
|
||||
{
|
||||
playerObject = NetworkManager != null
|
||||
? NetworkManager.SpawnManager.GetPlayerNetworkObject(clientId)
|
||||
: null;
|
||||
return playerObject != null;
|
||||
}
|
||||
|
||||
private void ConfigureSlots()
|
||||
{
|
||||
int count = Mathf.Min(slotsBottomToTop.Count, MaximumSlotCount);
|
||||
for (int index = 0; index < count; index++)
|
||||
{
|
||||
if (slotsBottomToTop[index] != null)
|
||||
slotsBottomToTop[index].Configure(this, index);
|
||||
}
|
||||
}
|
||||
|
||||
private int FindFirstValidRecipeIndex()
|
||||
{
|
||||
for (int index = 0; index < recipes.Count; index++)
|
||||
{
|
||||
if (IsRecipeValid(recipes[index]))
|
||||
return index;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
private bool TryGetRecipe(int index, out RocketAssemblyRecipe recipe)
|
||||
{
|
||||
if (index >= 0 && index < recipes.Count && IsRecipeValid(recipes[index]))
|
||||
{
|
||||
recipe = recipes[index];
|
||||
return true;
|
||||
}
|
||||
|
||||
recipe = null;
|
||||
return false;
|
||||
}
|
||||
|
||||
private bool IsValidSlotIndex(int slotIndex) =>
|
||||
slotIndex >= 0 && slotIndex < SlotCount && slotsBottomToTop[slotIndex] != null;
|
||||
|
||||
private static bool IsReadyRocketPart(NetworkItem item) =>
|
||||
item != null && item.IsSpawned && item.Definition != null &&
|
||||
item.Category == ItemCategory.RocketPart && item.Definition.IsAssemblyReady;
|
||||
|
||||
private static bool IsRecipeValid(RocketAssemblyRecipe recipe) =>
|
||||
recipe != null && recipe.IsConfigured;
|
||||
|
||||
private double GetNetworkTime() => NetworkManager != null
|
||||
? NetworkManager.ServerTime.Time
|
||||
: Time.timeAsDouble;
|
||||
|
||||
private void HandleStateChanged(
|
||||
RocketAssemblyWorkstationState _,
|
||||
RocketAssemblyWorkstationState __) => Changed?.Invoke();
|
||||
|
||||
private void HandleSelectedRecipeChanged(int _, int __) => Changed?.Invoke();
|
||||
private void HandleAssemblyTimeChanged(double _, double __) => Changed?.Invoke();
|
||||
private void HandleDefectiveStateChanged(bool _, bool __) => Changed?.Invoke();
|
||||
private void HandleSlotListChanged(NetworkListEvent<ulong> _) => Changed?.Invoke();
|
||||
}
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 43801e0a52c2499bbcf2c7e39871ce80
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,54 @@
|
||||
using Unity.Netcode;
|
||||
using UnityEngine;
|
||||
|
||||
[DisallowMultipleComponent]
|
||||
[RequireComponent(typeof(Collider))]
|
||||
public sealed class RocketAssemblyInputSlot : MonoBehaviour, IInteractable
|
||||
{
|
||||
[SerializeField] private Transform snapPoint;
|
||||
|
||||
private NetworkRocketAssemblyWorkstation workstation;
|
||||
private int slotIndex = -1;
|
||||
|
||||
public Transform SnapPoint => snapPoint != null ? snapPoint : transform;
|
||||
public Vector3 InteractionPosition => SnapPoint.position;
|
||||
public string InteractionPrompt => workstation != null
|
||||
? workstation.GetTakePrompt(slotIndex)
|
||||
: "Take part";
|
||||
public bool IsInteractionAvailable =>
|
||||
workstation != null && workstation.CanTakeSlotItem(slotIndex);
|
||||
|
||||
private void Reset()
|
||||
{
|
||||
snapPoint = transform;
|
||||
GetComponent<Collider>().isTrigger = true;
|
||||
}
|
||||
|
||||
private void OnValidate() => GetComponent<Collider>().isTrigger = true;
|
||||
|
||||
public void Configure(NetworkRocketAssemblyWorkstation owner, int index)
|
||||
{
|
||||
workstation = owner;
|
||||
slotIndex = index;
|
||||
}
|
||||
|
||||
public void RequestInteraction()
|
||||
{
|
||||
if (IsInteractionAvailable)
|
||||
workstation.RequestTakeSlotItem(slotIndex);
|
||||
}
|
||||
|
||||
private void OnTriggerEnter(Collider other) => TryInsert(other);
|
||||
|
||||
private void OnTriggerStay(Collider other) => TryInsert(other);
|
||||
|
||||
private void TryInsert(Collider other)
|
||||
{
|
||||
if (workstation == null || !workstation.IsServer || !workstation.IsSpawned)
|
||||
return;
|
||||
|
||||
NetworkItem item = other.GetComponentInParent<NetworkItem>();
|
||||
if (item != null)
|
||||
workstation.TryInsertItem(slotIndex, item);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 54737cf1ab274fdb851b89457fb3412f
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,89 @@
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
[CreateAssetMenu(
|
||||
fileName = "RocketAssemblyRecipe",
|
||||
menuName = "FORT-BO/Workstations/Rocket Assembly Recipe")]
|
||||
public sealed class RocketAssemblyRecipe : ScriptableObject
|
||||
{
|
||||
public const int MaximumPartCount = 9;
|
||||
|
||||
[Header("Recipe")]
|
||||
[SerializeField] private string recipeId;
|
||||
[SerializeField] private string displayName;
|
||||
[Tooltip("Exact assembly order. Element 0 is the lowest rocket part.")]
|
||||
[SerializeField] private List<ItemDefinition> requiredPartsBottomToTop = new();
|
||||
[SerializeField] private ItemDefinition outputItem;
|
||||
[SerializeField] private ItemDefinition defectiveOutputItem;
|
||||
[SerializeField, Min(0.05f)] private float assemblyDuration = 5f;
|
||||
|
||||
[Header("Blueprint")]
|
||||
[SerializeField] private string blueprintTitle;
|
||||
[SerializeField] private Sprite blueprintImage;
|
||||
|
||||
public string RecipeId => recipeId;
|
||||
public string DisplayName => string.IsNullOrWhiteSpace(displayName) ? name : displayName;
|
||||
public IReadOnlyList<ItemDefinition> RequiredPartsBottomToTop => requiredPartsBottomToTop;
|
||||
public int RequiredPartCount => requiredPartsBottomToTop.Count;
|
||||
public ItemDefinition OutputItem => outputItem;
|
||||
public ItemDefinition DefectiveOutputItem => defectiveOutputItem;
|
||||
public float AssemblyDuration => assemblyDuration;
|
||||
public string BlueprintTitle => string.IsNullOrWhiteSpace(blueprintTitle)
|
||||
? DisplayName
|
||||
: blueprintTitle;
|
||||
public Sprite BlueprintImage => blueprintImage;
|
||||
|
||||
public bool IsConfigured =>
|
||||
requiredPartsBottomToTop.Count is > 0 and <= MaximumPartCount &&
|
||||
requiredPartsBottomToTop.TrueForAll(IsReadyRocketPart) &&
|
||||
IsSpawnable(outputItem) &&
|
||||
IsSpawnable(defectiveOutputItem);
|
||||
|
||||
public bool Matches(IReadOnlyList<NetworkItem> slottedItems)
|
||||
{
|
||||
if (!IsConfigured || slottedItems == null ||
|
||||
slottedItems.Count < requiredPartsBottomToTop.Count)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
for (int index = 0; index < requiredPartsBottomToTop.Count; index++)
|
||||
{
|
||||
NetworkItem item = slottedItems[index];
|
||||
if (item == null || !MatchesDefinition(item, requiredPartsBottomToTop[index]))
|
||||
return false;
|
||||
}
|
||||
|
||||
for (int index = requiredPartsBottomToTop.Count; index < slottedItems.Count; index++)
|
||||
{
|
||||
if (slottedItems[index] != null)
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private void OnValidate()
|
||||
{
|
||||
recipeId = recipeId?.Trim().ToLowerInvariant();
|
||||
displayName = displayName?.Trim();
|
||||
blueprintTitle = blueprintTitle?.Trim();
|
||||
|
||||
if (requiredPartsBottomToTop.Count > MaximumPartCount)
|
||||
requiredPartsBottomToTop.RemoveRange(
|
||||
MaximumPartCount,
|
||||
requiredPartsBottomToTop.Count - MaximumPartCount);
|
||||
}
|
||||
|
||||
private static bool MatchesDefinition(NetworkItem item, ItemDefinition definition) =>
|
||||
item.Definition == definition ||
|
||||
(!string.IsNullOrEmpty(definition.ItemId) && item.ItemId == definition.ItemId);
|
||||
|
||||
private static bool IsReadyRocketPart(ItemDefinition definition) =>
|
||||
definition != null &&
|
||||
definition.Category == ItemCategory.RocketPart &&
|
||||
definition.IsAssemblyReady;
|
||||
|
||||
private static bool IsSpawnable(ItemDefinition definition) =>
|
||||
definition != null && definition.WorldPrefab != null;
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 04f3334793c14ee791f78059d0c2854c
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,148 @@
|
||||
using UnityEngine;
|
||||
using UnityEngine.Events;
|
||||
|
||||
[DisallowMultipleComponent]
|
||||
public sealed class RocketAssemblyWorkstationView : MonoBehaviour
|
||||
{
|
||||
[SerializeField] private NetworkRocketAssemblyWorkstation workstation;
|
||||
|
||||
[Header("State Events")]
|
||||
[SerializeField] private UnityEvent onLoading;
|
||||
[SerializeField] private UnityEvent onAssemblyStarted;
|
||||
[SerializeField] private UnityEvent onValidOutputReady;
|
||||
[SerializeField] private UnityEvent onDefectiveOutputReady;
|
||||
|
||||
[Header("Blueprint and Slot Events")]
|
||||
[SerializeField] private UnityEvent<string> onRecipeNameChanged;
|
||||
[SerializeField] private UnityEvent<string> onBlueprintTitleChanged;
|
||||
[SerializeField] private UnityEvent<Sprite> onBlueprintImageChanged;
|
||||
[SerializeField] private UnityEvent<int> onRequiredPartCountChanged;
|
||||
[SerializeField] private UnityEvent<int> onOccupiedSlotCountChanged;
|
||||
[SerializeField] private UnityEvent<bool> onCanStartChanged;
|
||||
|
||||
[Header("Continuous Progress")]
|
||||
[SerializeField] private UnityEvent<float> onAssemblyProgress;
|
||||
|
||||
private RocketAssemblyWorkstationState previousState;
|
||||
private bool previousDefectiveResult;
|
||||
private bool hasAppliedState;
|
||||
|
||||
public NetworkRocketAssemblyWorkstation Workstation => workstation;
|
||||
|
||||
private void Reset() =>
|
||||
workstation = GetComponentInParent<NetworkRocketAssemblyWorkstation>();
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
if (workstation == null)
|
||||
workstation = GetComponentInParent<NetworkRocketAssemblyWorkstation>();
|
||||
}
|
||||
|
||||
private void OnEnable()
|
||||
{
|
||||
if (workstation != null)
|
||||
{
|
||||
workstation.Changed += Apply;
|
||||
Apply();
|
||||
}
|
||||
}
|
||||
|
||||
private void Start() => Apply();
|
||||
|
||||
private void OnDisable()
|
||||
{
|
||||
if (workstation != null)
|
||||
workstation.Changed -= Apply;
|
||||
|
||||
hasAppliedState = false;
|
||||
}
|
||||
|
||||
private void Update()
|
||||
{
|
||||
if (workstation != null && workstation.IsOperating)
|
||||
onAssemblyProgress?.Invoke(workstation.AssemblyProgress);
|
||||
}
|
||||
|
||||
public void Apply()
|
||||
{
|
||||
if (workstation == null || !workstation.IsSpawned)
|
||||
return;
|
||||
|
||||
ApplyRecipeAndSlots();
|
||||
|
||||
RocketAssemblyWorkstationState currentState = workstation.State;
|
||||
bool defectiveResult = workstation.LastCompletedAssemblyWasDefective;
|
||||
if (hasAppliedState && currentState == previousState &&
|
||||
defectiveResult == previousDefectiveResult)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
previousState = currentState;
|
||||
previousDefectiveResult = defectiveResult;
|
||||
hasAppliedState = true;
|
||||
|
||||
switch (currentState)
|
||||
{
|
||||
case RocketAssemblyWorkstationState.Assembling:
|
||||
onAssemblyStarted?.Invoke();
|
||||
onAssemblyProgress?.Invoke(workstation.AssemblyProgress);
|
||||
break;
|
||||
|
||||
case RocketAssemblyWorkstationState.OutputReady:
|
||||
onAssemblyProgress?.Invoke(1f);
|
||||
if (defectiveResult)
|
||||
onDefectiveOutputReady?.Invoke();
|
||||
else
|
||||
onValidOutputReady?.Invoke();
|
||||
break;
|
||||
|
||||
default:
|
||||
onAssemblyProgress?.Invoke(0f);
|
||||
onLoading?.Invoke();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
[ContextMenu("Preview/Loading")]
|
||||
private void PreviewLoading()
|
||||
{
|
||||
onAssemblyProgress?.Invoke(0f);
|
||||
onLoading?.Invoke();
|
||||
}
|
||||
|
||||
[ContextMenu("Preview/Assembly Started")]
|
||||
private void PreviewAssemblyStarted()
|
||||
{
|
||||
onAssemblyProgress?.Invoke(0f);
|
||||
onAssemblyStarted?.Invoke();
|
||||
}
|
||||
|
||||
[ContextMenu("Preview/Assembly 50 Percent")]
|
||||
private void PreviewAssemblyHalfway() => onAssemblyProgress?.Invoke(0.5f);
|
||||
|
||||
[ContextMenu("Preview/Valid Output")]
|
||||
private void PreviewValidOutput()
|
||||
{
|
||||
onAssemblyProgress?.Invoke(1f);
|
||||
onValidOutputReady?.Invoke();
|
||||
}
|
||||
|
||||
[ContextMenu("Preview/Defective Output")]
|
||||
private void PreviewDefectiveOutput()
|
||||
{
|
||||
onAssemblyProgress?.Invoke(1f);
|
||||
onDefectiveOutputReady?.Invoke();
|
||||
}
|
||||
|
||||
private void ApplyRecipeAndSlots()
|
||||
{
|
||||
RocketAssemblyRecipe recipe = workstation.SelectedRecipe;
|
||||
onRecipeNameChanged?.Invoke(recipe != null ? recipe.DisplayName : string.Empty);
|
||||
onBlueprintTitleChanged?.Invoke(recipe != null ? recipe.BlueprintTitle : string.Empty);
|
||||
onBlueprintImageChanged?.Invoke(recipe != null ? recipe.BlueprintImage : null);
|
||||
onRequiredPartCountChanged?.Invoke(recipe != null ? recipe.RequiredPartCount : 0);
|
||||
onOccupiedSlotCountChanged?.Invoke(workstation.OccupiedSlotCount);
|
||||
onCanStartChanged?.Invoke(workstation.CanStartAssembly);
|
||||
}
|
||||
}
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 42a6ab0b475f46aebda93f3c671b670a
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
+5
-18
@@ -139,7 +139,9 @@ public sealed class NetworkItemProcessingWorkstation : NetworkWorkstationControl
|
||||
{
|
||||
if (!CanAcceptItem || item == null || !item.IsSpawned ||
|
||||
!TryFindRecipe(item, out int recipeIndex, out ItemProcessingRecipe recipe) ||
|
||||
!TryGetItemControl(item, out IWorkstationItemControl itemControl))
|
||||
!WorkstationItemControlUtility.TryGetControl(
|
||||
item,
|
||||
out IWorkstationItemControl itemControl))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@@ -200,7 +202,8 @@ public sealed class NetworkItemProcessingWorkstation : NetworkWorkstationControl
|
||||
outputObject.Spawn();
|
||||
|
||||
currentItem = outputObject.GetComponent<NetworkItem>();
|
||||
if (currentItem == null || !TryGetItemControl(currentItem, out _))
|
||||
if (currentItem == null ||
|
||||
!WorkstationItemControlUtility.TryGetControl(currentItem, out _))
|
||||
{
|
||||
Debug.LogError(
|
||||
$"{name} cannot produce '{recipe.OutputItem.DisplayName}': " +
|
||||
@@ -291,20 +294,4 @@ public sealed class NetworkItemProcessingWorkstation : NetworkWorkstationControl
|
||||
recipe != null && recipe.InputItem != null &&
|
||||
recipe.OutputItem != null && recipe.OutputItem.WorldPrefab != null;
|
||||
|
||||
private static bool TryGetItemControl(
|
||||
NetworkItem item,
|
||||
out IWorkstationItemControl itemControl)
|
||||
{
|
||||
foreach (MonoBehaviour component in item.GetComponents<MonoBehaviour>())
|
||||
{
|
||||
if (component is IWorkstationItemControl candidate)
|
||||
{
|
||||
itemControl = candidate;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
itemControl = null;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -257,8 +257,195 @@ MonoBehaviour:
|
||||
gameplaySceneName: Factory
|
||||
maxClientCount: 3
|
||||
useSecureRelay: 0
|
||||
--- !u!1 &1680150540
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 1
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
serializedVersion: 6
|
||||
m_Component:
|
||||
- component: {fileID: 1680150542}
|
||||
- component: {fileID: 1680150541}
|
||||
m_Layer: 0
|
||||
m_Name: '!ftraceLightmaps'
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!114 &1680150541
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 1
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 1680150540}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: b7fa80e7116296f4eb4f49ec1544ee22, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
renderSettingsBounces: 5
|
||||
renderSettingsGISamples: 16
|
||||
renderSettingsGIBackFaceWeight: 0
|
||||
renderSettingsTileSize: 512
|
||||
renderSettingsPriority: 2
|
||||
renderSettingsTexelsPerUnit: 20
|
||||
renderSettingsForceRefresh: 1
|
||||
renderSettingsForceRebuildGeometry: 1
|
||||
renderSettingsPerformRendering: 1
|
||||
renderSettingsUserRenderMode: 0
|
||||
renderSettingsDistanceShadowmask: 1
|
||||
renderSettingsSettingsMode: 0
|
||||
renderSettingsFixSeams: 1
|
||||
renderSettingsDenoise: 1
|
||||
renderSettingsDenoise2x: 0
|
||||
renderSettingsEncode: 1
|
||||
renderSettingsEncodeMode: 0
|
||||
renderSettingsOverwriteWarning: 0
|
||||
renderSettingsAutoAtlas: 1
|
||||
renderSettingsUnwrapUVs: 1
|
||||
renderSettingsForceDisableUnwrapUVs: 0
|
||||
renderSettingsMaxAutoResolution: 4096
|
||||
renderSettingsMinAutoResolution: 16
|
||||
renderSettingsUnloadScenes: 1
|
||||
renderSettingsAdjustSamples: 1
|
||||
renderSettingsCheckOverlaps: 0
|
||||
renderSettingsSkipOutOfBoundsUVs: 1
|
||||
renderSettingsHackEmissiveBoost: 1
|
||||
renderSettingsHackIndirectBoost: 1
|
||||
renderSettingsTempPath:
|
||||
renderSettingsOutPath: BakeryLightmaps
|
||||
renderSettingsUseScenePath: 0
|
||||
renderSettingsHackAOIntensity: 0
|
||||
renderSettingsHackAOSamples: 16
|
||||
renderSettingsHackAOSofter: 0
|
||||
renderSettingsHackAORadius: 1
|
||||
renderSettingsShowAOSettings: 0
|
||||
renderSettingsShowTasks: 1
|
||||
renderSettingsShowTasks2: 0
|
||||
renderSettingsShowPaths: 1
|
||||
renderSettingsShowNet: 1
|
||||
renderSettingsShowSettingsAsset: 1
|
||||
renderSettingsShowAPV: 0
|
||||
renderSettingsUseAPVSkyOcclusion: 0
|
||||
renderSettingsOcclusionProbes: 0
|
||||
renderSettingsTexelsPerMap: 0
|
||||
renderSettingsTexelsColor: 1
|
||||
renderSettingsTexelsMask: 1
|
||||
renderSettingsTexelsDir: 1
|
||||
renderSettingsShowDirWarning: 1
|
||||
renderSettingsRenderDirMode: 0
|
||||
renderSettingsShowCheckerSettings: 0
|
||||
renderSettingsSamplesWarning: 1
|
||||
renderSettingsSuppressPopups: 0
|
||||
renderSettingsSectorWarning: 0
|
||||
renderSettingsPrefabWarning: 1
|
||||
renderSettingsSplitByScene: 0
|
||||
renderSettingsSplitByTag: 0
|
||||
renderSettingsUVPaddingMax: 0
|
||||
renderSettingsUVPaddingPreserveIfExisted: 0
|
||||
renderSettingsPostPacking: 1
|
||||
renderSettingsHoleFilling: 0
|
||||
renderSettingsBruteForce: 1
|
||||
renderSettingsAlphaDithering: 0
|
||||
renderSettingsBeepOnFinish: 0
|
||||
renderSettingsExportTerrainAsHeightmap: 1
|
||||
renderSettingsRTXMode: 0
|
||||
renderSettingsLightProbeMode: 1
|
||||
renderSettingsClientMode: 0
|
||||
renderSettingsServerAddress: 127.0.0.1
|
||||
renderSettingsUnwrapper: 0
|
||||
renderSettingsDenoiserType: 100
|
||||
renderSettingsExportTerrainTrees: 0
|
||||
renderSettingsShowPerf: 1
|
||||
renderSettingsSampleDiv: 1
|
||||
renderSettingsAtlasPacker: 0
|
||||
renderSettingsBatchPoints: 1
|
||||
renderSettingsCompressVolumes: 0
|
||||
renderSettingsBatchAreaLightSampleLimit: 0
|
||||
renderSettingsSector: {fileID: 0}
|
||||
renderSettingsAsset: {fileID: 0}
|
||||
renderSettingsRTPVExport: 1
|
||||
renderSettingsRTPVSceneView: 0
|
||||
renderSettingsRTPVHDR: 0
|
||||
renderSettingsRTPVWidth: 640
|
||||
renderSettingsRTPVHeight: 360
|
||||
renderSettingsRTPVExposure: 1
|
||||
renderSettingsRemoveDuplicateLightmaps: 0
|
||||
lastBakeTime: 0
|
||||
enlightenWarningShown: 0
|
||||
enlightenWarningShown2: 0
|
||||
uniqueLights: []
|
||||
implicitGroups: []
|
||||
implicitGroupedObjects: []
|
||||
bounds: []
|
||||
hasEmissive:
|
||||
uvBuffOffsets:
|
||||
uvBuffLengths:
|
||||
uvSrcBuff: []
|
||||
uvDestBuff: []
|
||||
lmrIndicesOffsets:
|
||||
lmrIndicesLengths:
|
||||
lmrIndicesBuff:
|
||||
lmGroupLODResFlags:
|
||||
lmGroupMinLOD:
|
||||
lmGroupLODMatrix:
|
||||
serverGetFileList: []
|
||||
lightmapHasColor:
|
||||
lightmapHasMask:
|
||||
lightmapHasDir:
|
||||
lightmapHasRNM:
|
||||
lights: []
|
||||
modifiedAssetPathList: []
|
||||
modifiedAssets: []
|
||||
bakedRenderers: []
|
||||
nonBakedRenderers: []
|
||||
bakedLights: []
|
||||
bakedRenderersTerrain: []
|
||||
maps: []
|
||||
masks: []
|
||||
dirMaps: []
|
||||
rnmMaps0: []
|
||||
rnmMaps1: []
|
||||
rnmMaps2: []
|
||||
mapsMode:
|
||||
bakedIDs:
|
||||
bakedScaleOffset: []
|
||||
bakedVertexOffset:
|
||||
bakedVertexColorMesh: []
|
||||
bakedLightChannels:
|
||||
bakedIDsTerrain:
|
||||
bakedScaleOffsetTerrain: []
|
||||
assetList: []
|
||||
uvOverlapAssetList:
|
||||
idremap:
|
||||
usesRealtimeGI: 0
|
||||
emptyDirectionTex: {fileID: 0}
|
||||
anyVolumes: 0
|
||||
compressedVolumes: 0
|
||||
sectors: []
|
||||
prevBakedProbes: []
|
||||
prevBakedProbePos: []
|
||||
--- !u!4 &1680150542
|
||||
Transform:
|
||||
m_ObjectHideFlags: 1
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 1680150540}
|
||||
serializedVersion: 2
|
||||
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
||||
m_LocalPosition: {x: 0, y: 0, z: 0}
|
||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||
m_ConstrainProportionsScale: 0
|
||||
m_Children: []
|
||||
m_Father: {fileID: 0}
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
--- !u!1660057539 &9223372036854775807
|
||||
SceneRoots:
|
||||
m_ObjectHideFlags: 0
|
||||
m_Roots:
|
||||
- {fileID: 535045610}
|
||||
- {fileID: 1680150542}
|
||||
|
||||
+12069
-1575
File diff suppressed because one or more lines are too long
@@ -2618,3 +2618,60 @@ launch3
|
||||
launch4
|
||||
$
|
||||
Done
|
||||
2026-8-13
|
||||
Init...
|
||||
Context created
|
||||
Tiles: 1
|
||||
Loading shader denoisePrepareOIDN.ptx::oxMain...
|
||||
Loaded
|
||||
Loading shader denoiseFinishOIDN.ptx::oxMain...
|
||||
Loaded
|
||||
launch1
|
||||
launch2
|
||||
launch3
|
||||
launch4
|
||||
^
|
||||
launch1
|
||||
launch2
|
||||
launch3
|
||||
launch4
|
||||
$
|
||||
Done
|
||||
2026-8-13
|
||||
Init...
|
||||
Context created
|
||||
Tiles: 1
|
||||
Loading shader denoisePrepareOIDN.ptx::oxMain...
|
||||
Loaded
|
||||
Loading shader denoiseFinishOIDN.ptx::oxMain...
|
||||
Loaded
|
||||
launch1
|
||||
launch2
|
||||
launch3
|
||||
launch4
|
||||
^
|
||||
launch1
|
||||
launch2
|
||||
launch3
|
||||
launch4
|
||||
$
|
||||
Done
|
||||
2026-8-13
|
||||
Init...
|
||||
Context created
|
||||
Tiles: 1
|
||||
Loading shader denoisePrepareOIDN.ptx::oxMain...
|
||||
Loaded
|
||||
Loading shader denoiseFinishOIDN.ptx::oxMain...
|
||||
Loaded
|
||||
launch1
|
||||
launch2
|
||||
launch3
|
||||
launch4
|
||||
^
|
||||
launch1
|
||||
launch2
|
||||
launch3
|
||||
launch4
|
||||
$
|
||||
Done
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1770,115 +1770,101 @@ Error reading command from socketError reading command from socketError reading
|
||||
[main 2026-08-13T12:59:38.178Z] [WorktreeCleanupMainService] Granted cleanup lease id=8 owner=window:1 reason="scheduled-worktree-cleanup"
|
||||
[main 2026-08-13T12:59:44.170Z] [WorktreeCleanupMainService] Releasing cleanup lease id=8 owner=window:1 reason="scheduled-worktree-cleanup" releaseReason="released" heldForMs=5992
|
||||
[main 2026-08-13T13:28:49.235Z] update#recheckOutdatedUpdateOnResume - re-checking pending update freshness unlock-screen
|
||||
smooth UV pos...
|
||||
Rendering UV GBuffer for Factory_LMA4 51
|
||||
RGBA32F...RGBA8...R8...RGBA8_SRGB...RGBA16F...states...
|
||||
Rendering UV normal...
|
||||
Rendering faceted UV normal...
|
||||
Rendering UV pos...
|
||||
Rendering smooth UV pos...
|
||||
Rendering UV GBuffer for volumes 512
|
||||
RGBA32F...RGBA8...R8...RGBA8_SRGB...RGBA16F...states...
|
||||
Done
|
||||
Done
|
||||
Running ftraceRTX fixpos3D "C:\Users\42\AppData\Local\Temp\frender" "uvpos_volumes.lz4" 2 0 5 fixPos3D_5.bin
|
||||
Running ftraceRTX fixpos12 "C:\Users\42\AppData\Local\Temp\frender" "uvpos_Factory_LMA3.lz4" 2 0 3 0
|
||||
Running ftraceRTX fixpos12 "C:\Users\42\AppData\Local\Temp\frender" "uvpos_Factory_LMA4.lz4" 2 0 4 0
|
||||
Running ftraceRTX fixpos12 "C:\Users\42\AppData\Local\Temp\frender" "uvpos_Factory_LMA2.lz4" 2 0 2 0
|
||||
Running ftraceRTX fixpos12 "C:\Users\42\AppData\Local\Temp\frender" "uvpos_Factory_LMA1.lz4" 2 0 1 0
|
||||
Running ftraceRTX fixpos12 "C:\Users\42\AppData\Local\Temp\frender" "uvpos_Factory_LM0.lz4" 2 0 0 0
|
||||
Running ftraceRTX arealightprobesh "C:\Users\42\AppData\Local\Temp\frender" "light_1_5" 1924 0 5 lights0.bin
|
||||
Running ftraceRTX batchpointlightprobeshlegacy "C:\Users\42\AppData\Local\Temp\frender" "PointBatch_5_0_4" 1924 0 5 batchpointlight_5_0_4.bin
|
||||
Running ftraceRTX addmul "C:\Users\42\AppData\Local\Temp\frender" "volumes" 4 0 5 comp_5.bin
|
||||
Running ftraceRTX arealight "C:\Users\42\AppData\Local\Temp\frender" "light_1_3" 4 0 3 lights0.bin
|
||||
Running ftraceRTX batchpointlightlegacy "C:\Users\42\AppData\Local\Temp\frender" "PointBatch_3_0_4" 4 0 3 batchpointlight_3_0_4.bin
|
||||
Running ftraceRTX addmul "C:\Users\42\AppData\Local\Temp\frender" "Factory_LMA3" 4 0 3 comp_3.bin
|
||||
Running ftraceRTX arealight "C:\Users\42\AppData\Local\Temp\frender" "light_1_4" 4 0 4 lights0.bin
|
||||
Running ftraceRTX batchpointlightlegacy "C:\Users\42\AppData\Local\Temp\frender" "PointBatch_4_0_4" 4 0 4 batchpointlight_4_0_4.bin
|
||||
Running ftraceRTX addmul "C:\Users\42\AppData\Local\Temp\frender" "Factory_LMA4" 4 0 4 comp_4.bin
|
||||
Running ftraceRTX arealight "C:\Users\42\AppData\Local\Temp\frender" "light_1_2" 4 0 2 lights0.bin
|
||||
Running ftraceRTX batchpointlightlegacy "C:\Users\42\AppData\Local\Temp\frender" "PointBatch_2_0_4" 4 0 2 batchpointlight_2_0_4.bin
|
||||
Running ftraceRTX addmul "C:\Users\42\AppData\Local\Temp\frender" "Factory_LMA2" 4 0 2 comp_2.bin
|
||||
Running ftraceRTX arealight "C:\Users\42\AppData\Local\Temp\frender" "light_1_1" 4 0 1 lights0.bin
|
||||
Running ftraceRTX batchpointlightlegacy "C:\Users\42\AppData\Local\Temp\frender" "PointBatch_1_0_4" 4 0 1 batchpointlight_1_0_4.bin
|
||||
Running ftraceRTX addmul "C:\Users\42\AppData\Local\Temp\frender" "Factory_LMA1" 4 0 1 comp_1.bin
|
||||
Running ftraceRTX arealight "C:\Users\42\AppData\Local\Temp\frender" "light_1_0" 4 0 0 lights0.bin
|
||||
Running ftraceRTX addmul "C:\Users\42\AppData\Local\Temp\frender" "Factory_LM0" 4 0 0 comp_0.bin
|
||||
Running ftraceRTX texgi "C:\Users\42\AppData\Local\Temp\frender" "Factory_LMA3_diffuse" 4 16 3 "gi_Factory_LMA30.bin" "Factory_LMA3_diffuse0_HDR.lz4" vbTraceTex.bin
|
||||
Running ftraceRTX texgi "C:\Users\42\AppData\Local\Temp\frender" "Factory_LMA4_diffuse" 4 16 4 "gi_Factory_LMA40.bin" "Factory_LMA4_diffuse0_HDR.lz4" vbTraceTex.bin
|
||||
Running ftraceRTX texgi "C:\Users\42\AppData\Local\Temp\frender" "Factory_LMA2_diffuse" 4 16 2 "gi_Factory_LMA20.bin" "Factory_LMA2_diffuse0_HDR.lz4" vbTraceTex.bin
|
||||
Running ftraceRTX texgi "C:\Users\42\AppData\Local\Temp\frender" "Factory_LMA1_diffuse" 4 16 1 "gi_Factory_LMA10.bin" "Factory_LMA1_diffuse0_HDR.lz4" vbTraceTex.bin
|
||||
Running ftraceRTX texgi "C:\Users\42\AppData\Local\Temp\frender" "Factory_LM0_diffuse" 4 16 0 "gi_Factory_LM00.bin" "Factory_LM0_diffuse0_HDR.lz4" vbTraceTex.bin
|
||||
Running ftraceRTX texgi "C:\Users\42\AppData\Local\Temp\frender" "Factory_LMA3_diffuse" 4 16 3 "gi_Factory_LMA31.bin" "Factory_LMA3_diffuse0_HDR.lz4" vbTraceTex.bin
|
||||
Running ftraceRTX texgi "C:\Users\42\AppData\Local\Temp\frender" "Factory_LMA4_diffuse" 4 16 4 "gi_Factory_LMA41.bin" "Factory_LMA4_diffuse0_HDR.lz4" vbTraceTex.bin
|
||||
Running ftraceRTX texgi "C:\Users\42\AppData\Local\Temp\frender" "Factory_LMA2_diffuse" 4 16 2 "gi_Factory_LMA21.bin" "Factory_LMA2_diffuse0_HDR.lz4" vbTraceTex.bin
|
||||
Running ftraceRTX texgi "C:\Users\42\AppData\Local\Temp\frender" "Factory_LMA1_diffuse" 4 16 1 "gi_Factory_LMA11.bin" "Factory_LMA1_diffuse0_HDR.lz4" vbTraceTex.bin
|
||||
Running ftraceRTX texgi "C:\Users\42\AppData\Local\Temp\frender" "Factory_LM0_diffuse" 4 16 0 "gi_Factory_LM01.bin" "Factory_LM0_diffuse0_HDR.lz4" vbTraceTex.bin
|
||||
Running ftraceRTX texgi "C:\Users\42\AppData\Local\Temp\frender" "Factory_LMA3_diffuse" 4 16 3 "gi_Factory_LMA32.bin" "Factory_LMA3_diffuse0_HDR.lz4" vbTraceTex.bin
|
||||
Running ftraceRTX texgi "C:\Users\42\AppData\Local\Temp\frender" "Factory_LMA4_diffuse" 4 16 4 "gi_Factory_LMA42.bin" "Factory_LMA4_diffuse0_HDR.lz4" vbTraceTex.bin
|
||||
Running ftraceRTX texgi "C:\Users\42\AppData\Local\Temp\frender" "Factory_LMA2_diffuse" 4 16 2 "gi_Factory_LMA22.bin" "Factory_LMA2_diffuse0_HDR.lz4" vbTraceTex.bin
|
||||
Running ftraceRTX texgi "C:\Users\42\AppData\Local\Temp\frender" "Factory_LMA1_diffuse" 4 16 1 "gi_Factory_LMA12.bin" "Factory_LMA1_diffuse0_HDR.lz4" vbTraceTex.bin
|
||||
Running ftraceRTX texgi "C:\Users\42\AppData\Local\Temp\frender" "Factory_LM0_diffuse" 4 16 0 "gi_Factory_LM02.bin" "Factory_LM0_diffuse0_HDR.lz4" vbTraceTex.bin
|
||||
Running ftraceRTX texgi "C:\Users\42\AppData\Local\Temp\frender" "Factory_LMA3_diffuse" 4 16 3 "gi_Factory_LMA33.bin" "Factory_LMA3_diffuse0_HDR.lz4" vbTraceTex.bin
|
||||
Running ftraceRTX texgi "C:\Users\42\AppData\Local\Temp\frender" "Factory_LMA4_diffuse" 4 16 4 "gi_Factory_LMA43.bin" "Factory_LMA4_diffuse0_HDR.lz4" vbTraceTex.bin
|
||||
Running ftraceRTX texgi "C:\Users\42\AppData\Local\Temp\frender" "Factory_LMA2_diffuse" 4 16 2 "gi_Factory_LMA23.bin" "Factory_LMA2_diffuse0_HDR.lz4" vbTraceTex.bin
|
||||
Running ftraceRTX texgi "C:\Users\42\AppData\Local\Temp\frender" "Factory_LMA1_diffuse" 4 16 1 "gi_Factory_LMA13.bin" "Factory_LMA1_diffuse0_HDR.lz4" vbTraceTex.bin
|
||||
Running ftraceRTX texgi "C:\Users\42\AppData\Local\Temp\frender" "Factory_LM0_diffuse" 4 16 0 "gi_Factory_LM03.bin" "Factory_LM0_diffuse0_HDR.lz4" vbTraceTex.bin
|
||||
Running ftraceRTX texgiprobesh "C:\Users\42\AppData\Local\Temp\frender" "volumes_final" 1924 16 5 "gi_volumes4.bin" "volumes_lights_HDR.lz4" vbTraceTex.bin
|
||||
Running ftraceRTX texgi "C:\Users\42\AppData\Local\Temp\frender" "Factory_LMA3_final" 4 16 3 "gi_Factory_LMA34.bin" "Factory_LMA3_lights_HDR.lz4" vbTraceTex.bin
|
||||
Running ftraceRTX texgi "C:\Users\42\AppData\Local\Temp\frender" "Factory_LMA4_final" 4 16 4 "gi_Factory_LMA44.bin" "Factory_LMA4_lights_HDR.lz4" vbTraceTex.bin
|
||||
Running ftraceRTX texgi "C:\Users\42\AppData\Local\Temp\frender" "Factory_LMA2_final" 4 16 2 "gi_Factory_LMA24.bin" "Factory_LMA2_lights_HDR.lz4" vbTraceTex.bin
|
||||
Running ftraceRTX texgi "C:\Users\42\AppData\Local\Temp\frender" "Factory_LMA1_final" 4 16 1 "gi_Factory_LMA14.bin" "Factory_LMA1_lights_HDR.lz4" vbTraceTex.bin
|
||||
Running ftraceRTX texgi "C:\Users\42\AppData\Local\Temp\frender" "Factory_LM0_final" 4 16 0 "gi_Factory_LM04.bin" "Factory_LM0_lights_HDR.lz4" vbTraceTex.bin
|
||||
Running ftraceRTX addsh "C:\Users\42\AppData\Local\Temp\frender" "volumes_final_" 4 0 5 shcomp_5.bin
|
||||
Running denoiserOIDN c "C:\Users\42\AppData\Local\Temp\frender/Factory_LMA3_final_HDR.lz4" "C:\Users\42\AppData\Local\Temp\frender/Factory_LMA3_final_HDR.lz4" 4096 0
|
||||
Running seamfixer "C:\Users\42\AppData\Local\Temp\frender" "3" "Factory_LMA3_final_HDR.lz4"
|
||||
Running denoiserOIDN c "C:\Users\42\AppData\Local\Temp\frender/Factory_LMA4_final_HDR.lz4" "C:\Users\42\AppData\Local\Temp\frender/Factory_LMA4_final_HDR.lz4" 2048 0
|
||||
Running seamfixer "C:\Users\42\AppData\Local\Temp\frender" "4" "Factory_LMA4_final_HDR.lz4"
|
||||
Running denoiserOIDN c "C:\Users\42\AppData\Local\Temp\frender/Factory_LMA2_final_HDR.lz4" "C:\Users\42\AppData\Local\Temp\frender/Factory_LMA2_final_HDR.lz4" 4096 0
|
||||
Running seamfixer "C:\Users\42\AppData\Local\Temp\frender" "2" "Factory_LMA2_final_HDR.lz4"
|
||||
Running denoiserOIDN c "C:\Users\42\AppData\Local\Temp\frender/Factory_LMA1_final_HDR.lz4" "C:\Users\42\AppData\Local\Temp\frender/Factory_LMA1_final_HDR.lz4" 4096 0
|
||||
Running seamfixer "C:\Users\42\AppData\Local\Temp\frender" "1" "Factory_LMA1_final_HDR.lz4"
|
||||
Running denoiserOIDN c "C:\Users\42\AppData\Local\Temp\frender/Factory_LM0_final_HDR.lz4" "C:\Users\42\AppData\Local\Temp\frender/Factory_LM0_final_HDR.lz4" 4096 0
|
||||
Running seamfixer "C:\Users\42\AppData\Local\Temp\frender" "0" "Factory_LM0_final_HDR.lz4"
|
||||
Running halffloat2hdr "C:\Users\42\AppData\Local\Temp\frender/Factory_LMA3_final_HDR.lz4" "D:/UnityProjects/FORT-BO/Assets/BakeryLightmaps/Factory_LMA3_final.hdr" 1024
|
||||
Running halffloat2hdr "C:\Users\42\AppData\Local\Temp\frender/Factory_LMA4_final_HDR.lz4" "D:/UnityProjects/FORT-BO/Assets/BakeryLightmaps/Factory_LMA4_final.hdr" 1024
|
||||
Running halffloat2hdr "C:\Users\42\AppData\Local\Temp\frender/Factory_LMA2_final_HDR.lz4" "D:/UnityProjects/FORT-BO/Assets/BakeryLightmaps/Factory_LMA2_final.hdr" 1024
|
||||
Running halffloat2hdr "C:\Users\42\AppData\Local\Temp\frender/Factory_LMA1_final_HDR.lz4" "D:/UnityProjects/FORT-BO/Assets/BakeryLightmaps/Factory_LMA1_final.hdr" 1024
|
||||
Running halffloat2hdr "C:\Users\42\AppData\Local\Temp\frender/Factory_LM0_final_HDR.lz4" "D:/UnityProjects/FORT-BO/Assets/BakeryLightmaps/Factory_LM0_final.hdr" 1024
|
||||
Done
|
||||
Done
|
||||
Done
|
||||
Done
|
||||
Loaded vertex shader: quad.vso
|
||||
Loaded pixel shader: skyOutput.pso
|
||||
Loaded pixel shader: cookieOutput.pso
|
||||
initShaders done
|
||||
initScene done
|
||||
Done
|
||||
Rendering UV GBuffer for Factory_LM0 51
|
||||
RGBA32F...RGBA8...R8...RGBA8_SRGB...RGBA16F...states...
|
||||
Rendering UV normal...
|
||||
Rendering faceted UV normal...
|
||||
Rendering UV pos...
|
||||
Rendering smooth UV pos...
|
||||
Rendering UV GBuffer for Factory_LMA1 51
|
||||
RGBA32F...RGBA8...R8...RGBA8_SRGB...RGBA16F...states...
|
||||
Rendering UV normal...
|
||||
Rendering faceted UV normal...
|
||||
Rendering UV pos...
|
||||
Rendering smooth UV pos...
|
||||
Rendering UV GBuffer for Factory_LMA2 51
|
||||
RGBA32F...RGBA8...R8...RGBA8_SRGB...RGBA16F...states...
|
||||
Rendering UV normal...
|
||||
Rendering faceted UV normal...
|
||||
Rendering UV pos...
|
||||
Rendering smooth UV pos...
|
||||
Rendering UV GBuffer for Factory_LMA3 51
|
||||
RGBA32F...RGBA8...R8...RGBA8_SRGB...RGBA16F...states...
|
||||
Rendering UV normal...
|
||||
Rendering faceted UV normal...
|
||||
Rendering UV pos...
|
||||
[main 2026-08-13T18:59:38.212Z] [WorktreeCleanupMainService] Granted cleanup lease id=9 owner=window:1 reason="scheduled-worktree-cleanup"
|
||||
[main 2026-08-13T18:59:44.179Z] [WorktreeCleanupMainService] Releasing cleanup lease id=9 owner=window:1 reason="scheduled-worktree-cleanup" releaseReason="released" heldForMs=5967
|
||||
[main 2026-08-14T00:59:38.203Z] [WorktreeCleanupMainService] Granted cleanup lease id=10 owner=window:1 reason="scheduled-worktree-cleanup"
|
||||
[main 2026-08-14T00:59:44.179Z] [WorktreeCleanupMainService] Releasing cleanup lease id=10 owner=window:1 reason="scheduled-worktree-cleanup" releaseReason="released" heldForMs=5976
|
||||
[main 2026-08-14T05:01:32.825Z] update#recheckOutdatedUpdateOnResume - re-checking pending update freshness unlock-screen
|
||||
[main 2026-08-14T05:04:38.218Z] Extension host with pid 33520 exited with code: 0, signal: unknown.
|
||||
[main 2026-08-14T05:04:38.228Z] Extension host with pid 24564 exited with code: 0, signal: unknown.
|
||||
[main 2026-08-14T05:04:38.342Z] Extension host with pid 11744 exited with code: 0, signal: unknown.
|
||||
[main 2026-08-14T05:06:03.618Z] [LocalAgentStorage] Scanned 0 recent databases (skipped 8 old), found 75 agent headers, deduped to 75
|
||||
[main 2026-08-14T05:06:16.170Z] [CursorProclistService] Config enabled feature (subsample every 10s; memoryPressureMonitorEnabled=true)
|
||||
[main 2026-08-14T05:06:39.794Z] Extension host with pid 8144 exited with code: 0, signal: unknown.
|
||||
[main 2026-08-14T05:10:49.914Z] [PowerMainService] Started wakelock id=2 owner=window:2 reason="agent-loop" activeCount=1
|
||||
[main 2026-08-14T05:10:49.958Z] [PowerMainService] Disabled background throttling id=3 owner=window:2 reason="agent-loop" activeCount=1
|
||||
[main 2026-08-14T05:12:14.043Z] Extension host with pid 40716 exited with code: 0, signal: unknown.
|
||||
[main 2026-08-14T05:17:21.272Z] Extension host with pid 10328 exited with code: 0, signal: unknown.
|
||||
[main 2026-08-14T05:22:11.383Z] [PowerMainService] Stopping wakelock id=2 owner=window:2 reason="agent-loop" heldForMs=681469
|
||||
[main 2026-08-14T05:22:11.395Z] [PowerMainService] Stopped background throttling disable id=3 owner=window:2 reason="agent-loop" heldForMs=681438
|
||||
[main 2026-08-14T05:22:20.233Z] Extension host with pid 25752 exited with code: 0, signal: unknown.
|
||||
[main 2026-08-14T05:27:15.717Z] Extension host with pid 16988 exited with code: 0, signal: unknown.
|
||||
[main 2026-08-14T05:32:48.118Z] Extension host with pid 47688 exited with code: 0, signal: unknown.
|
||||
[main 2026-08-14T05:35:45.352Z] [PowerMainService] Started wakelock id=3 owner=window:2 reason="agent-loop" activeCount=1
|
||||
[main 2026-08-14T05:35:45.384Z] [PowerMainService] Disabled background throttling id=4 owner=window:2 reason="agent-loop" activeCount=1
|
||||
[main 2026-08-14T05:37:27.754Z] Extension host with pid 44784 exited with code: 0, signal: unknown.
|
||||
[main 2026-08-14T05:42:36.984Z] Extension host with pid 47720 exited with code: 0, signal: unknown.
|
||||
[main 2026-08-14T05:43:52.043Z] [PowerMainService] Stopping wakelock id=3 owner=window:2 reason="agent-loop" heldForMs=486691
|
||||
[main 2026-08-14T05:43:52.052Z] [PowerMainService] Stopped background throttling disable id=4 owner=window:2 reason="agent-loop" heldForMs=486668
|
||||
[main 2026-08-14T05:47:45.593Z] Extension host with pid 25724 exited with code: 0, signal: unknown.
|
||||
[main 2026-08-14T05:52:43.392Z] Extension host with pid 19272 exited with code: 0, signal: unknown.
|
||||
[main 2026-08-14T05:58:15.316Z] Extension host with pid 39880 exited with code: 0, signal: unknown.
|
||||
[main 2026-08-14T06:02:50.935Z] Extension host with pid 9148 exited with code: 0, signal: unknown.
|
||||
[main 2026-08-14T06:08:15.474Z] Extension host with pid 47036 exited with code: 0, signal: unknown.
|
||||
[main 2026-08-14T06:12:51.110Z] Extension host with pid 34384 exited with code: 0, signal: unknown.
|
||||
[main 2026-08-14T06:18:05.815Z] Extension host with pid 28972 exited with code: 0, signal: unknown.
|
||||
[main 2026-08-14T06:23:05.929Z] Extension host with pid 25408 exited with code: 0, signal: unknown.
|
||||
[main 2026-08-14T06:28:06.242Z] Extension host with pid 24092 exited with code: 0, signal: unknown.
|
||||
[main 2026-08-14T06:31:14.571Z] Extension host with pid 47920 exited with code: 0, signal: unknown.
|
||||
[main 2026-08-14T06:37:15.573Z] Extension host with pid 9708 exited with code: 0, signal: unknown.
|
||||
[main 2026-08-14T06:43:06.404Z] Extension host with pid 19928 exited with code: 0, signal: unknown.
|
||||
[main 2026-08-14T06:47:43.398Z] Extension host with pid 9772 exited with code: 0, signal: unknown.
|
||||
[main 2026-08-14T06:52:43.401Z] Extension host with pid 3724 exited with code: 0, signal: unknown.
|
||||
[main 2026-08-14T06:57:43.399Z] Extension host with pid 36720 exited with code: 0, signal: unknown.
|
||||
[main 2026-08-14T06:59:38.183Z] [WorktreeCleanupMainService] Granted cleanup lease id=11 owner=window:1 reason="scheduled-worktree-cleanup"
|
||||
[main 2026-08-14T06:59:44.167Z] [WorktreeCleanupMainService] Releasing cleanup lease id=11 owner=window:1 reason="scheduled-worktree-cleanup" releaseReason="released" heldForMs=5984
|
||||
[main 2026-08-14T07:03:04.711Z] Extension host with pid 26132 exited with code: 0, signal: unknown.
|
||||
[main 2026-08-14T07:08:09.881Z] Extension host with pid 40752 exited with code: 0, signal: unknown.
|
||||
[main 2026-08-14T07:13:10.059Z] Extension host with pid 27356 exited with code: 0, signal: unknown.
|
||||
[main 2026-08-14T07:18:44.713Z] Extension host with pid 42060 exited with code: 0, signal: unknown.
|
||||
[main 2026-08-14T07:23:15.498Z] Extension host with pid 17108 exited with code: 0, signal: unknown.
|
||||
[main 2026-08-14T07:28:15.575Z] Extension host with pid 19348 exited with code: 0, signal: unknown.
|
||||
[main 2026-08-14T07:33:10.526Z] Extension host with pid 47448 exited with code: 0, signal: unknown.
|
||||
[main 2026-08-14T07:38:45.189Z] Extension host with pid 3564 exited with code: 0, signal: unknown.
|
||||
[main 2026-08-14T07:44:56.958Z] Extension host with pid 31520 exited with code: 0, signal: unknown.
|
||||
[main 2026-08-14T07:48:07.997Z] Extension host with pid 45788 exited with code: 0, signal: unknown.
|
||||
[main 2026-08-14T07:54:40.439Z] Extension host with pid 42196 exited with code: 0, signal: unknown.
|
||||
[main 2026-08-14T07:57:19.037Z] Extension host with pid 14848 exited with code: 0, signal: unknown.
|
||||
[main 2026-08-14T08:03:40.145Z] Extension host with pid 38192 exited with code: 0, signal: unknown.
|
||||
[main 2026-08-14T08:09:08.240Z] Extension host with pid 47256 exited with code: 0, signal: unknown.
|
||||
[main 2026-08-14T08:13:28.518Z] Extension host with pid 26572 exited with code: 0, signal: unknown.
|
||||
[main 2026-08-14T08:19:08.686Z] Extension host with pid 49012 exited with code: 0, signal: unknown.
|
||||
[main 2026-08-14T08:23:11.409Z] Extension host with pid 8620 exited with code: 0, signal: unknown.
|
||||
[main 2026-08-14T08:31:04.682Z] Extension host with pid 40560 exited with code: 0, signal: unknown.
|
||||
[main 2026-08-14T08:38:11.944Z] Extension host with pid 49596 exited with code: 0, signal: unknown.
|
||||
[main 2026-08-14T08:42:08.462Z] Extension host with pid 48264 exited with code: 0, signal: unknown.
|
||||
[main 2026-08-14T08:48:15.704Z] Extension host with pid 34148 exited with code: 0, signal: unknown.
|
||||
[main 2026-08-14T08:54:09.264Z] Extension host with pid 49520 exited with code: 0, signal: unknown.
|
||||
[main 2026-08-14T08:57:15.933Z] Extension host with pid 49328 exited with code: 0, signal: unknown.
|
||||
[main 2026-08-14T09:03:40.044Z] Extension host with pid 47712 exited with code: 0, signal: unknown.
|
||||
[main 2026-08-14T09:09:12.607Z] Extension host with pid 49428 exited with code: 0, signal: unknown.
|
||||
[main 2026-08-14T09:14:15.758Z] Extension host with pid 36984 exited with code: 0, signal: unknown.
|
||||
[main 2026-08-14T09:19:10.085Z] Extension host with pid 30996 exited with code: 0, signal: unknown.
|
||||
[main 2026-08-14T09:24:15.809Z] Extension host with pid 49280 exited with code: 0, signal: unknown.
|
||||
[main 2026-08-14T09:31:23.972Z] Extension host with pid 49904 exited with code: 0, signal: unknown.
|
||||
[main 2026-08-14T09:38:10.330Z] Extension host with pid 49800 exited with code: 0, signal: unknown.
|
||||
[main 2026-08-14T09:43:15.857Z] Extension host with pid 50084 exited with code: 0, signal: unknown.
|
||||
[main 2026-08-14T09:47:21.577Z] Extension host with pid 49248 exited with code: 0, signal: unknown.
|
||||
[main 2026-08-14T09:53:40.039Z] Extension host with pid 48800 exited with code: 0, signal: unknown.
|
||||
[main 2026-08-14T09:58:43.440Z] Extension host with pid 49076 exited with code: 0, signal: unknown.
|
||||
[main 2026-08-14T10:00:05.241Z] update#recheckOutdatedUpdateOnResume - re-checking pending update freshness unlock-screen
|
||||
[main 2026-08-14T10:04:43.542Z] Extension host with pid 50000 exited with code: 0, signal: unknown.
|
||||
[main 2026-08-14T10:10:41.947Z] Extension host with pid 48488 exited with code: 0, signal: unknown.
|
||||
[main 2026-08-14T10:14:05.745Z] Extension host with pid 48636 exited with code: 0, signal: unknown.
|
||||
[main 2026-08-14T10:14:53.444Z] [PowerMainService] Started wakelock id=4 owner=window:2 reason="agent-loop" activeCount=1
|
||||
[main 2026-08-14T10:14:53.501Z] [PowerMainService] Disabled background throttling id=5 owner=window:2 reason="agent-loop" activeCount=1
|
||||
[main 2026-08-14T10:16:17.690Z] Extension host with pid 11668 exited with code: 0, signal: unknown.
|
||||
[main 2026-08-14T10:18:11.434Z] Extension host with pid 42640 exited with code: 0, signal: unknown.
|
||||
[main 2026-08-14T10:19:33.655Z] [PowerMainService] Stopping wakelock id=4 owner=window:2 reason="agent-loop" heldForMs=280211
|
||||
[main 2026-08-14T10:19:33.670Z] [PowerMainService] Stopped background throttling disable id=5 owner=window:2 reason="agent-loop" heldForMs=280169
|
||||
[main 2026-08-14T10:23:14.945Z] Extension host with pid 37328 exited with code: 0, signal: unknown.
|
||||
[main 2026-08-14T10:24:24.913Z] Extension host with pid 27428 exited with code: 0, signal: unknown.
|
||||
[main 2026-08-14T10:24:24.928Z] Extension host with pid 5416 exited with code: 0, signal: unknown.
|
||||
[main 2026-08-14T10:24:51.877Z] Extension host with pid 25348 exited with code: 1073807364, signal: unknown.
|
||||
[main 2026-08-14T10:24:51.883Z] Extension host with pid 40864 exited with code: 1073807364, signal: unknown.
|
||||
[main 2026-08-14T10:24:51.904Z] Extension host with pid 34948 exited with code: 1073807364, signal: unknown.
|
||||
[main 2026-08-14T10:24:52.799Z] Win32UpdateService: system shutdown detected; skipping updates.
|
||||
V pos...
|
||||
Rendering smooth UV pos...
|
||||
Rendering UV GBuffer for Factory_LMA4 51
|
||||
RGBA32F...RGBA8...R8...RGBA8_SRGB...RGBA16F...states...
|
||||
@@ -3590,3 +3576,81 @@ Running seamfixer "C:\Users\42\AppData\Local\Temp\frender" "0" "Factory_LM0_fina
|
||||
Running halffloat2hdr "C:\Users\42\AppData\Local\Temp\frender/Factory_LMA1_final_HDR.lz4" "D:/UnityProjects/FORT-BO/Assets/BakeryLightmaps/Factory_LMA1_final.hdr" 1024
|
||||
Running halffloat2hdr "C:\Users\42\AppData\Local\Temp\frender/Factory_LMA2_final_HDR.lz4" "D:/UnityProjects/FORT-BO/Assets/BakeryLightmaps/Factory_LMA2_final.hdr" 1024
|
||||
Running halffloat2hdr "C:\Users\42\AppData\Local\Temp\frender/Factory_LM0_final_HDR.lz4" "D:/UnityProjects/FORT-BO/Assets/BakeryLightmaps/Factory_LM0_final.hdr" 1024
|
||||
Done
|
||||
Done
|
||||
Done
|
||||
Done
|
||||
Loaded vertex shader: quad.vso
|
||||
Loaded pixel shader: skyOutput.pso
|
||||
Loaded pixel shader: cookieOutput.pso
|
||||
initShaders done
|
||||
initScene done
|
||||
Done
|
||||
Rendering UV GBuffer for Factory_LM0 51
|
||||
RGBA32F...RGBA8...R8...RGBA8_SRGB...RGBA16F...states...
|
||||
Rendering UV normal...
|
||||
Rendering faceted UV normal...
|
||||
Rendering UV pos...
|
||||
Rendering smooth UV pos...
|
||||
Rendering UV GBuffer for Factory_LMA1 51
|
||||
RGBA32F...RGBA8...R8...RGBA8_SRGB...RGBA16F...states...
|
||||
Rendering UV normal...
|
||||
Rendering faceted UV normal...
|
||||
Rendering UV pos...
|
||||
Rendering smooth UV pos...
|
||||
Rendering UV GBuffer for Factory_LMA2 51
|
||||
RGBA32F...RGBA8...R8...RGBA8_SRGB...RGBA16F...states...
|
||||
Rendering UV normal...
|
||||
Rendering faceted UV normal...
|
||||
Rendering UV pos...
|
||||
Rendering smooth UV pos...
|
||||
Rendering UV GBuffer for volumes 512
|
||||
RGBA32F...RGBA8...R8...RGBA8_SRGB...RGBA16F...states...
|
||||
Done
|
||||
Done
|
||||
Running ftraceRTX fixpos3D "C:\Users\42\AppData\Local\Temp\frender" "uvpos_volumes.lz4" 2 0 3 fixPos3D_3.bin
|
||||
Running ftraceRTX fixpos12 "C:\Users\42\AppData\Local\Temp\frender" "uvpos_Factory_LMA1.lz4" 2 0 1 0
|
||||
Running ftraceRTX fixpos12 "C:\Users\42\AppData\Local\Temp\frender" "uvpos_Factory_LMA2.lz4" 2 0 2 0
|
||||
Running ftraceRTX fixpos12 "C:\Users\42\AppData\Local\Temp\frender" "uvpos_Factory_LM0.lz4" 2 0 0 0
|
||||
Running ftraceRTX arealightprobesh "C:\Users\42\AppData\Local\Temp\frender" "light_1_3" 1924 0 3 lights0.bin
|
||||
Running ftraceRTX arealightprobesh "C:\Users\42\AppData\Local\Temp\frender" "light_2_3" 1924 0 3 lights1.bin
|
||||
Running ftraceRTX batchpointlightprobeshlegacy "C:\Users\42\AppData\Local\Temp\frender" "PointBatch_3_0_14" 1924 0 3 batchpointlight_3_0_14.bin
|
||||
Running ftraceRTX addmul "C:\Users\42\AppData\Local\Temp\frender" "volumes" 4 0 3 comp_3.bin
|
||||
Running ftraceRTX arealight "C:\Users\42\AppData\Local\Temp\frender" "light_1_1" 4 0 1 lights0.bin
|
||||
Running ftraceRTX arealight "C:\Users\42\AppData\Local\Temp\frender" "light_2_1" 4 0 1 lights1.bin
|
||||
Running ftraceRTX batchpointlightlegacy "C:\Users\42\AppData\Local\Temp\frender" "PointBatch_1_0_14" 4 0 1 batchpointlight_1_0_14.bin
|
||||
Running ftraceRTX addmul "C:\Users\42\AppData\Local\Temp\frender" "Factory_LMA1" 4 0 1 comp_1.bin
|
||||
Running ftraceRTX arealight "C:\Users\42\AppData\Local\Temp\frender" "light_1_2" 4 0 2 lights0.bin
|
||||
Running ftraceRTX arealight "C:\Users\42\AppData\Local\Temp\frender" "light_2_2" 4 0 2 lights1.bin
|
||||
Running ftraceRTX batchpointlightlegacy "C:\Users\42\AppData\Local\Temp\frender" "PointBatch_2_0_14" 4 0 2 batchpointlight_2_0_14.bin
|
||||
Running ftraceRTX addmul "C:\Users\42\AppData\Local\Temp\frender" "Factory_LMA2" 4 0 2 comp_2.bin
|
||||
Running ftraceRTX arealight "C:\Users\42\AppData\Local\Temp\frender" "light_1_0" 4 0 0 lights0.bin
|
||||
Running ftraceRTX arealight "C:\Users\42\AppData\Local\Temp\frender" "light_2_0" 4 0 0 lights1.bin
|
||||
Running ftraceRTX batchpointlightlegacy "C:\Users\42\AppData\Local\Temp\frender" "PointBatch_0_0_14" 4 0 0 batchpointlight_0_0_14.bin
|
||||
Running ftraceRTX addmul "C:\Users\42\AppData\Local\Temp\frender" "Factory_LM0" 4 0 0 comp_0.bin
|
||||
Running ftraceRTX texgi "C:\Users\42\AppData\Local\Temp\frender" "Factory_LMA1_diffuse" 4 16 1 "gi_Factory_LMA10.bin" "Factory_LMA1_diffuse0_HDR.lz4" vbTraceTex.bin
|
||||
Running ftraceRTX texgi "C:\Users\42\AppData\Local\Temp\frender" "Factory_LMA2_diffuse" 4 16 2 "gi_Factory_LMA20.bin" "Factory_LMA2_diffuse0_HDR.lz4" vbTraceTex.bin
|
||||
Running ftraceRTX texgi "C:\Users\42\AppData\Local\Temp\frender" "Factory_LM0_diffuse" 4 16 0 "gi_Factory_LM00.bin" "Factory_LM0_diffuse0_HDR.lz4" vbTraceTex.bin
|
||||
Running ftraceRTX texgi "C:\Users\42\AppData\Local\Temp\frender" "Factory_LMA1_diffuse" 4 16 1 "gi_Factory_LMA11.bin" "Factory_LMA1_diffuse0_HDR.lz4" vbTraceTex.bin
|
||||
Running ftraceRTX texgi "C:\Users\42\AppData\Local\Temp\frender" "Factory_LMA2_diffuse" 4 16 2 "gi_Factory_LMA21.bin" "Factory_LMA2_diffuse0_HDR.lz4" vbTraceTex.bin
|
||||
Running ftraceRTX texgi "C:\Users\42\AppData\Local\Temp\frender" "Factory_LM0_diffuse" 4 16 0 "gi_Factory_LM01.bin" "Factory_LM0_diffuse0_HDR.lz4" vbTraceTex.bin
|
||||
Running ftraceRTX texgi "C:\Users\42\AppData\Local\Temp\frender" "Factory_LMA1_diffuse" 4 16 1 "gi_Factory_LMA12.bin" "Factory_LMA1_diffuse0_HDR.lz4" vbTraceTex.bin
|
||||
Running ftraceRTX texgi "C:\Users\42\AppData\Local\Temp\frender" "Factory_LMA2_diffuse" 4 16 2 "gi_Factory_LMA22.bin" "Factory_LMA2_diffuse0_HDR.lz4" vbTraceTex.bin
|
||||
Running ftraceRTX texgi "C:\Users\42\AppData\Local\Temp\frender" "Factory_LM0_diffuse" 4 16 0 "gi_Factory_LM02.bin" "Factory_LM0_diffuse0_HDR.lz4" vbTraceTex.bin
|
||||
Running ftraceRTX texgi "C:\Users\42\AppData\Local\Temp\frender" "Factory_LMA1_diffuse" 4 16 1 "gi_Factory_LMA13.bin" "Factory_LMA1_diffuse0_HDR.lz4" vbTraceTex.bin
|
||||
Running ftraceRTX texgi "C:\Users\42\AppData\Local\Temp\frender" "Factory_LMA2_diffuse" 4 16 2 "gi_Factory_LMA23.bin" "Factory_LMA2_diffuse0_HDR.lz4" vbTraceTex.bin
|
||||
Running ftraceRTX texgi "C:\Users\42\AppData\Local\Temp\frender" "Factory_LM0_diffuse" 4 16 0 "gi_Factory_LM03.bin" "Factory_LM0_diffuse0_HDR.lz4" vbTraceTex.bin
|
||||
Running ftraceRTX texgiprobesh "C:\Users\42\AppData\Local\Temp\frender" "volumes_final" 1924 16 3 "gi_volumes4.bin" "volumes_lights_HDR.lz4" vbTraceTex.bin
|
||||
Running ftraceRTX texgi "C:\Users\42\AppData\Local\Temp\frender" "Factory_LMA1_final" 4 16 1 "gi_Factory_LMA14.bin" "Factory_LMA1_lights_HDR.lz4" vbTraceTex.bin
|
||||
Running ftraceRTX texgi "C:\Users\42\AppData\Local\Temp\frender" "Factory_LMA2_final" 4 16 2 "gi_Factory_LMA24.bin" "Factory_LMA2_lights_HDR.lz4" vbTraceTex.bin
|
||||
Running ftraceRTX texgi "C:\Users\42\AppData\Local\Temp\frender" "Factory_LM0_final" 4 16 0 "gi_Factory_LM04.bin" "Factory_LM0_lights_HDR.lz4" vbTraceTex.bin
|
||||
Running ftraceRTX addsh "C:\Users\42\AppData\Local\Temp\frender" "volumes_final_" 4 0 3 shcomp_3.bin
|
||||
Running denoiserOIDN c "C:\Users\42\AppData\Local\Temp\frender/Factory_LMA1_final_HDR.lz4" "C:\Users\42\AppData\Local\Temp\frender/Factory_LMA1_final_HDR.lz4" 4096 0
|
||||
Running seamfixer "C:\Users\42\AppData\Local\Temp\frender" "1" "Factory_LMA1_final_HDR.lz4"
|
||||
Running denoiserOIDN c "C:\Users\42\AppData\Local\Temp\frender/Factory_LMA2_final_HDR.lz4" "C:\Users\42\AppData\Local\Temp\frender/Factory_LMA2_final_HDR.lz4" 4096 0
|
||||
Running seamfixer "C:\Users\42\AppData\Local\Temp\frender" "2" "Factory_LMA2_final_HDR.lz4"
|
||||
Running denoiserOIDN c "C:\Users\42\AppData\Local\Temp\frender/Factory_LM0_final_HDR.lz4" "C:\Users\42\AppData\Local\Temp\frender/Factory_LM0_final_HDR.lz4" 4096 0
|
||||
Running seamfixer "C:\Users\42\AppData\Local\Temp\frender" "0" "Factory_LM0_final_HDR.lz4"
|
||||
Running halffloat2hdr "C:\Users\42\AppData\Local\Temp\frender/Factory_LMA1_final_HDR.lz4" "D:/UnityProjects/FORT-BO/Assets/BakeryLightmaps/Factory_LMA1_final.hdr" 1024
|
||||
Running halffloat2hdr "C:\Users\42\AppData\Local\Temp\frender/Factory_LMA2_final_HDR.lz4" "D:/UnityProjects/FORT-BO/Assets/BakeryLightmaps/Factory_LMA2_final.hdr" 1024
|
||||
Running halffloat2hdr "C:\Users\42\AppData\Local\Temp\frender/Factory_LM0_final_HDR.lz4" "D:/UnityProjects/FORT-BO/Assets/BakeryLightmaps/Factory_LM0_final.hdr" 1024
|
||||
|
||||
@@ -114,12 +114,12 @@
|
||||
{
|
||||
"type": "System.Int32, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089",
|
||||
"key": "ShapeBuilder.ActiveShapeIndex",
|
||||
"value": "{\"m_Value\":7}"
|
||||
"value": "{\"m_Value\":6}"
|
||||
},
|
||||
{
|
||||
"type": "UnityEngine.Vector3, UnityEngine.CoreModule, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null",
|
||||
"key": "ShapeBuilder.LastSize.Cube",
|
||||
"value": "{\"m_Value\":{\"x\":-0.100006103515625,\"y\":0.6000000238418579,\"z\":-0.10000038146972656}}"
|
||||
"value": "{\"m_Value\":{\"x\":2.4000015258789064,\"y\":1.5000001192092896,\"z\":0.20000076293945313}}"
|
||||
},
|
||||
{
|
||||
"type": "UnityEngine.Vector3, UnityEngine.CoreModule, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null",
|
||||
@@ -329,7 +329,7 @@
|
||||
{
|
||||
"type": "UnityEngine.ProBuilder.SelectMode, Unity.ProBuilder, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null",
|
||||
"key": "s_SelectMode",
|
||||
"value": "{\"m_Value\":1}"
|
||||
"value": "{\"m_Value\":4}"
|
||||
},
|
||||
{
|
||||
"type": "UnityEngine.ProBuilder.ExtrudeMethod, Unity.ProBuilder, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null",
|
||||
|
||||
@@ -39,3 +39,4 @@
|
||||
08.13.2026 17:38 | example_volumes_simple | 0h 0m 6s
|
||||
08.13.2026 17:45 | Factory | 0h 0m 40s
|
||||
08.13.2026 17:54 | Factory | 0h 0m 47s
|
||||
08.13.2026 17:56 | Factory | 0h 0m 44s
|
||||
|
||||
Reference in New Issue
Block a user