Add concealment meter and skinned collider baker; reorganize assets
- ConcealmentMeter: standalone component measuring the percentage of the character volume embedded inside environment geometry (bake -> voxelize via column ray-stabbing parity -> classify interior voxels against box/sphere/ capsule/convex colliders and terrain). Always-on, throttled, gizmo debug. - SkinnedColliderBaker: sole per-frame collider bake owner for skinned rigs. MeshPainter now delegates baking and only borrows BakedMesh for the GPU raster and cache refresh, so the collider stays fresh outside paint mode. - Move pose assets to Assets/Poses, retire unused Insect scripts to Assets/Unused, restore Paintman.controller; mode scripts and scene updated. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
1 parent
def10541ab
commit
dcfd668422
29 files changed
+2160
-1656
No files matched your search
@@ -0,0 +1,335 @@
|
||||
using UnityEngine;
|
||||
#if ENABLE_INPUT_SYSTEM
|
||||
using UnityEngine.InputSystem;
|
||||
#endif
|
||||
|
||||
/// <summary>
|
||||
/// Gravity-free "insect" surface walker: crawls along any surface (floors, ramps,
|
||||
/// walls, ceilings, around convex/concave edges) regardless of slope. No
|
||||
/// CharacterController, no Rigidbody — the transform is moved kinematically and
|
||||
/// re-stuck to the surface every frame via sphere casts.
|
||||
///
|
||||
/// Each step: WASD is taken camera-relative (the camera stays world-up) and
|
||||
/// projected onto the current surface tangent plane, the body advances along that
|
||||
/// plane, then a small set of probes re-finds the surface to follow:
|
||||
/// 1. a wall directly ahead (concave corner) becomes the new ground,
|
||||
/// 2. otherwise a down-cast (into the surface) keeps the body stuck on
|
||||
/// flat/ramped/concave ground,
|
||||
/// 3. otherwise a forward-sweeping cast wraps the body over a convex edge.
|
||||
/// The body's up is aligned to the surface normal; its forward faces the move
|
||||
/// direction. Designed to coexist with <see cref="PlayerCharacterController"/> on
|
||||
/// the same GameObject, toggled by the GameModeManager (only one is enabled).
|
||||
/// </summary>
|
||||
[DisallowMultipleComponent]
|
||||
public class InsectController : MonoBehaviour
|
||||
{
|
||||
[Header("Movement")]
|
||||
[Tooltip("Crawl speed along the surface (units/second).")]
|
||||
public float moveSpeed = 4f;
|
||||
|
||||
[Tooltip("Speed multiplier while the sprint key (Left Shift) is held.")]
|
||||
public float sprintSpeedMultiplier = 1.8f;
|
||||
|
||||
[Tooltip("How snappily the body re-aligns its up to the surface normal and turns toward the move direction (1/second; higher = tighter).")]
|
||||
public float alignSmoothing = 16f;
|
||||
|
||||
[Header("Camera")]
|
||||
[Tooltip("Interpret WASD relative to the camera (projected onto the surface). Off = world X/Z axes projected onto the surface.")]
|
||||
public bool cameraRelative = true;
|
||||
|
||||
[Tooltip("Camera used for camera-relative movement. Empty = Camera.main.")]
|
||||
public Transform cameraTransform;
|
||||
|
||||
[Header("Surface Sticking")]
|
||||
[Tooltip("Distance kept between the transform origin and the surface it walks on (tune to the character's pivot; 0 = origin sits on the surface).")]
|
||||
public float hoverHeight = 0f;
|
||||
|
||||
[Tooltip("Radius of the probe spheres. Roughly the body's half-width; keeps the walker off sharp edges.")]
|
||||
public float probeRadius = 0.3f;
|
||||
|
||||
[Tooltip("How far the body can step up onto a rise or drop down a dip while staying stuck.")]
|
||||
public float stepHeight = 0.4f;
|
||||
|
||||
[Tooltip("Surfaces the walker can stick to.")]
|
||||
public LayerMask groundMask = ~0;
|
||||
|
||||
[Header("Edge Wrapping")]
|
||||
[Tooltip("A surface ahead steeper than this (degrees from the current up) is treated as a wall to climb into (concave corner).")]
|
||||
[Range(5f, 90f)]
|
||||
public float wallWrapAngle = 35f;
|
||||
|
||||
[Tooltip("How far ahead to look for a wall to climb into.")]
|
||||
public float wallProbeDistance = 0.6f;
|
||||
|
||||
[Tooltip("Largest angle the body wraps around a convex edge in one step (degrees). Higher = follows sharper outside corners.")]
|
||||
[Range(30f, 170f)]
|
||||
public float maxWrapAngle = 150f;
|
||||
|
||||
[Header("Animation (optional)")]
|
||||
public Animator animator;
|
||||
|
||||
[Tooltip("Animator bool set true while crawling.")]
|
||||
public string runningParameter = "Running";
|
||||
|
||||
/// <summary>When false, input is ignored (the body holds its surface pose).</summary>
|
||||
public bool ControlEnabled { get; set; } = true;
|
||||
|
||||
/// <summary>True after the last step found a surface to stick to.</summary>
|
||||
public bool OnSurface => _onSurface;
|
||||
|
||||
/// <summary>Surface normal the body is currently stuck to (its up).</summary>
|
||||
public Vector3 SurfaceNormal => _surfaceNormal;
|
||||
|
||||
private const float RunningSpeedThresholdSqr = 0.04f; // (0.2 m/s)^2
|
||||
private const float Eps = 1e-5f;
|
||||
|
||||
private int _runningHash;
|
||||
private bool _onSurface;
|
||||
private Vector3 _surfaceNormal = Vector3.up;
|
||||
private Vector3 _lastMove;
|
||||
private readonly RaycastHit[] _hits = new RaycastHit[16];
|
||||
|
||||
void Awake()
|
||||
{
|
||||
_runningHash = Animator.StringToHash(runningParameter);
|
||||
if (!cameraTransform && Camera.main)
|
||||
cameraTransform = Camera.main.transform;
|
||||
if (groundMask.value == 0)
|
||||
groundMask = ~0;
|
||||
_surfaceNormal = transform.up;
|
||||
}
|
||||
|
||||
void Update()
|
||||
{
|
||||
float h = 0f, v = 0f;
|
||||
bool sprinting = false;
|
||||
|
||||
if (ControlEnabled)
|
||||
{
|
||||
#if ENABLE_INPUT_SYSTEM
|
||||
var keyboard = Keyboard.current;
|
||||
if (keyboard != null)
|
||||
{
|
||||
if (keyboard.aKey.isPressed) h -= 1f;
|
||||
if (keyboard.dKey.isPressed) h += 1f;
|
||||
if (keyboard.sKey.isPressed) v -= 1f;
|
||||
if (keyboard.wKey.isPressed) v += 1f;
|
||||
sprinting = keyboard.leftShiftKey.isPressed;
|
||||
}
|
||||
#else
|
||||
h = Input.GetAxisRaw("Horizontal");
|
||||
v = Input.GetAxisRaw("Vertical");
|
||||
sprinting = Input.GetKey(KeyCode.LeftShift);
|
||||
#endif
|
||||
}
|
||||
|
||||
Step(h, v, sprinting, Time.deltaTime);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Advances the body one frame: projects the (h,v) input onto the surface,
|
||||
/// moves along it, re-sticks to the surface and re-orients. Public so it can be
|
||||
/// driven deterministically in tests (set <see cref="cameraRelative"/> false to
|
||||
/// map input to world axes without a camera).
|
||||
/// </summary>
|
||||
public void Step(float h, float v, bool sprinting, float dt)
|
||||
{
|
||||
Vector3 up = transform.up;
|
||||
Vector3 wish = InputToWorld(up, h, v);
|
||||
float inputMag = Mathf.Clamp01(new Vector2(h, v).magnitude);
|
||||
float speed = sprinting ? moveSpeed * sprintSpeedMultiplier : moveSpeed;
|
||||
|
||||
Vector3 move = wish * (speed * inputMag * dt);
|
||||
Vector3 tentative = transform.position + move;
|
||||
_lastMove = move;
|
||||
|
||||
if (ProbeSurface(tentative, up, wish, out Vector3 point, out Vector3 normal)
|
||||
&& normal.sqrMagnitude > Eps)
|
||||
{
|
||||
normal.Normalize();
|
||||
transform.position = point + normal * hoverHeight;
|
||||
_surfaceNormal = normal;
|
||||
_onSurface = true;
|
||||
OrientTo(normal, wish, dt);
|
||||
}
|
||||
else
|
||||
{
|
||||
// No surface within reach (e.g. ran off the end of geometry): keep
|
||||
// crawling along the last tangent instead of falling.
|
||||
transform.position = tentative;
|
||||
_onSurface = false;
|
||||
}
|
||||
|
||||
if (animator)
|
||||
animator.SetBool(_runningHash, _onSurface && inputMag > 0f
|
||||
&& _lastMove.sqrMagnitude / Mathf.Max(dt * dt, 1e-8f) > RunningSpeedThresholdSqr);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Immediately probes straight into the current surface and places the body on
|
||||
/// it (no smoothing). Used when entering insect mode so the first frame is stuck.
|
||||
/// </summary>
|
||||
public void SnapToSurface()
|
||||
{
|
||||
Vector3 up = transform.up;
|
||||
if (ProbeSurface(transform.position, up, Vector3.zero, out Vector3 point, out Vector3 normal)
|
||||
&& normal.sqrMagnitude > Eps)
|
||||
{
|
||||
normal.Normalize();
|
||||
transform.position = point + normal * hoverHeight;
|
||||
_surfaceNormal = normal;
|
||||
_onSurface = true;
|
||||
Vector3 fwd = Vector3.ProjectOnPlane(transform.forward, normal);
|
||||
if (fwd.sqrMagnitude < Eps) fwd = Vector3.ProjectOnPlane(transform.right, normal);
|
||||
if (fwd.sqrMagnitude > Eps)
|
||||
transform.rotation = Quaternion.LookRotation(fwd.normalized, normal);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Maps WASD to a world-space direction in the surface tangent plane. The camera
|
||||
/// stays world-up, so its axes are projected onto the plane; if an axis is nearly
|
||||
/// parallel to the surface normal (on a wall/ceiling) it is rebuilt from the other
|
||||
/// axis so the mapping never collapses.
|
||||
/// </summary>
|
||||
private Vector3 InputToWorld(Vector3 up, float h, float v)
|
||||
{
|
||||
Vector3 right, fwd;
|
||||
if (cameraRelative && cameraTransform)
|
||||
{
|
||||
right = Vector3.ProjectOnPlane(cameraTransform.right, up);
|
||||
fwd = Vector3.ProjectOnPlane(cameraTransform.forward, up);
|
||||
}
|
||||
else
|
||||
{
|
||||
right = Vector3.ProjectOnPlane(Vector3.right, up);
|
||||
fwd = Vector3.ProjectOnPlane(Vector3.forward, up);
|
||||
}
|
||||
|
||||
if (fwd.sqrMagnitude < Eps) fwd = Vector3.Cross(right, up);
|
||||
if (right.sqrMagnitude < Eps) right = Vector3.Cross(up, fwd);
|
||||
if (fwd.sqrMagnitude < Eps || right.sqrMagnitude < Eps)
|
||||
return Vector3.zero;
|
||||
|
||||
Vector3 dir = right.normalized * h + fwd.normalized * v;
|
||||
return dir.sqrMagnitude > 1f ? dir.normalized : dir;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Finds the surface the body should stick to at <paramref name="pos"/>, trying in
|
||||
/// order: a wall ahead (concave corner), the ground below (flat/ramp/concave), a
|
||||
/// convex edge wrap. Returns the surface contact point and normal.
|
||||
/// </summary>
|
||||
private bool ProbeSurface(Vector3 pos, Vector3 up, Vector3 moveDir, out Vector3 point, out Vector3 normal)
|
||||
{
|
||||
bool moving = moveDir.sqrMagnitude > Eps;
|
||||
// Lift the sideways/edge probes clear of the surface we are already on, so the
|
||||
// probe sphere never starts penetrating it (which would self-hit or, worse, make
|
||||
// SphereCast report a bogus point at the world origin on an initial overlap).
|
||||
Vector3 probeOrigin = pos + up * Mathf.Max(hoverHeight, probeRadius + 0.05f);
|
||||
|
||||
// 1) Concave corner: a wall right in front becomes the new ground to climb into.
|
||||
if (moving)
|
||||
{
|
||||
Vector3 d = moveDir.normalized;
|
||||
if (CastBest(probeOrigin, d, probeRadius + wallProbeDistance, out Vector3 wp, out Vector3 wn)
|
||||
&& Vector3.Angle(wn, up) > wallWrapAngle)
|
||||
{
|
||||
point = wp; normal = wn; return true;
|
||||
}
|
||||
}
|
||||
|
||||
// 2) Ground follow: cast from above the body straight into the surface.
|
||||
float startUp = hoverHeight + stepHeight;
|
||||
float downDist = startUp + hoverHeight + stepHeight + probeRadius;
|
||||
if (CastBest(pos + up * startUp, -up, downDist, out Vector3 gp, out Vector3 gn))
|
||||
{
|
||||
point = gp; normal = gn; return true;
|
||||
}
|
||||
|
||||
// 3) Convex edge: the surface curved away ahead. Sweep the down-probe forward,
|
||||
// pitching it over the edge until it catches the wrapped surface.
|
||||
if (moving)
|
||||
{
|
||||
Vector3 axis = Vector3.Cross(moveDir.normalized, up);
|
||||
if (axis.sqrMagnitude > Eps)
|
||||
{
|
||||
axis.Normalize();
|
||||
float reach = hoverHeight + stepHeight + probeRadius + 0.5f;
|
||||
for (float ang = 20f; ang <= maxWrapAngle; ang += 20f)
|
||||
{
|
||||
Vector3 d = Quaternion.AngleAxis(ang, axis) * (-up);
|
||||
if (CastBest(probeOrigin, d, reach, out Vector3 ep, out Vector3 en))
|
||||
{
|
||||
point = ep; normal = en; return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
point = pos; normal = up; return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sphere-casts and returns the nearest hit that is not our own collider and has a
|
||||
/// usable (non-zero) normal. False if nothing valid was hit.
|
||||
/// </summary>
|
||||
private bool CastBest(Vector3 origin, Vector3 dir, float dist, out Vector3 point, out Vector3 normal)
|
||||
{
|
||||
point = origin;
|
||||
normal = Vector3.zero;
|
||||
if (dir.sqrMagnitude < Eps)
|
||||
return false;
|
||||
|
||||
int n = Physics.SphereCastNonAlloc(
|
||||
origin, probeRadius, dir.normalized, _hits, dist, groundMask, QueryTriggerInteraction.Ignore);
|
||||
|
||||
float best = float.MaxValue;
|
||||
bool found = false;
|
||||
for (int i = 0; i < n; i++)
|
||||
{
|
||||
RaycastHit hit = _hits[i];
|
||||
if (!hit.collider || hit.collider.transform.IsChildOf(transform))
|
||||
continue;
|
||||
// A zero distance means the sphere started inside the collider; Unity then
|
||||
// reports point=(0,0,0) and normal=-dir, which would teleport us — discard it.
|
||||
if (hit.distance <= 1e-4f || hit.normal.sqrMagnitude < Eps)
|
||||
continue;
|
||||
if (hit.distance < best)
|
||||
{
|
||||
best = hit.distance;
|
||||
point = hit.point;
|
||||
normal = hit.normal;
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
return found;
|
||||
}
|
||||
|
||||
/// <summary>Eases the body's up toward the surface normal and its forward toward the move direction.</summary>
|
||||
private void OrientTo(Vector3 normal, Vector3 wish, float dt)
|
||||
{
|
||||
Vector3 fwd = Vector3.ProjectOnPlane(wish, normal);
|
||||
// When the move/forward is parallel to the new normal (walking straight into a
|
||||
// wall), fall back to the old up projected onto the surface: that points "up the
|
||||
// wall", so the body keeps climbing instead of snapping a 90-degree yaw.
|
||||
if (fwd.sqrMagnitude < Eps) fwd = Vector3.ProjectOnPlane(transform.forward, normal);
|
||||
if (fwd.sqrMagnitude < Eps) fwd = Vector3.ProjectOnPlane(transform.up, normal);
|
||||
if (fwd.sqrMagnitude < Eps) fwd = Vector3.ProjectOnPlane(transform.right, normal);
|
||||
if (fwd.sqrMagnitude < Eps)
|
||||
return;
|
||||
|
||||
Quaternion target = Quaternion.LookRotation(fwd.normalized, normal);
|
||||
float t = alignSmoothing > 0f ? 1f - Mathf.Exp(-alignSmoothing * dt) : 1f;
|
||||
transform.rotation = Quaternion.Slerp(transform.rotation, target, t);
|
||||
}
|
||||
|
||||
void OnDrawGizmosSelected()
|
||||
{
|
||||
Gizmos.color = Color.cyan;
|
||||
Vector3 c = transform.position + transform.up * hoverHeight;
|
||||
Gizmos.DrawWireSphere(c, probeRadius);
|
||||
Gizmos.color = Color.green;
|
||||
Gizmos.DrawLine(c, c + _surfaceNormal * 0.5f);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: bf4039bad99e6e64aae35786e6a87ba6
|
||||
@@ -0,0 +1,38 @@
|
||||
/// <summary>
|
||||
/// Insect / surface-walk mode: the player crawls along any surface (walls, ceilings,
|
||||
/// arbitrary slopes) via <see cref="InsectController"/>. The gravity-based
|
||||
/// <see cref="PlayerCharacterController"/> is disabled so the two never fight. The
|
||||
/// camera keeps its world-up orbit; painting is off.
|
||||
/// </summary>
|
||||
public class InsectMode : GameMode
|
||||
{
|
||||
public override string DisplayName => "Insect";
|
||||
|
||||
public override void Enter()
|
||||
{
|
||||
if (Manager.Player)
|
||||
Manager.Player.enabled = false; // stop the gravity controller (its Update/gravity)
|
||||
|
||||
//if (Manager.Insect)
|
||||
//{
|
||||
// Manager.Insect.enabled = true;
|
||||
// Manager.Insect.ControlEnabled = true;
|
||||
// Manager.Insect.SnapToSurface();
|
||||
//}
|
||||
|
||||
if (Manager.CameraInput)
|
||||
Manager.CameraInput.LookMode = ThirdPersonOrbitInput.OrbitLookMode.AlwaysActive;
|
||||
|
||||
if (Manager.Painter)
|
||||
Manager.Painter.PaintingEnabled = false;
|
||||
}
|
||||
|
||||
public override void Exit()
|
||||
{
|
||||
//if (Manager.Insect)
|
||||
// Manager.Insect.enabled = false;
|
||||
|
||||
if (Manager.Player)
|
||||
Manager.Player.enabled = true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5e82ea3f59c643648a33cf33b32dba58
|
||||
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: bccbff0e6a6dcb54bbe58022842213f4
|
||||
PrefabImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,219 @@
|
||||
%YAML 1.1
|
||||
%TAG !u! tag:unity3d.com,2011:
|
||||
--- !u!1 &2753207977301565134
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
serializedVersion: 6
|
||||
m_Component:
|
||||
- component: {fileID: 7343299364369393213}
|
||||
- component: {fileID: 22507459658410499}
|
||||
m_Layer: 0
|
||||
m_Name: Player (Variant 2, Hand)
|
||||
m_TagString: Player
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!4 &7343299364369393213
|
||||
Transform:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 2753207977301565134}
|
||||
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:
|
||||
- {fileID: 4014907164611811682}
|
||||
- {fileID: 1262072125491596160}
|
||||
m_Father: {fileID: 0}
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
--- !u!114 &22507459658410499
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 2753207977301565134}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: bf4039bad99e6e64aae35786e6a87ba6, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier: Assembly-CSharp::InsectController
|
||||
moveSpeed: 4
|
||||
sprintSpeedMultiplier: 1.8
|
||||
alignSmoothing: 16
|
||||
cameraRelative: 1
|
||||
cameraTransform: {fileID: 0}
|
||||
hoverHeight: 0.1
|
||||
probeRadius: 0.5
|
||||
stepHeight: 0.3
|
||||
groundMask:
|
||||
serializedVersion: 2
|
||||
m_Bits: 4294967295
|
||||
wallWrapAngle: 70
|
||||
wallProbeDistance: 0.6
|
||||
maxWrapAngle: 150
|
||||
animator: {fileID: 0}
|
||||
runningParameter: Running
|
||||
--- !u!1 &9012401119129405183
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
serializedVersion: 6
|
||||
m_Component:
|
||||
- component: {fileID: 1262072125491596160}
|
||||
m_Layer: 0
|
||||
m_Name: CameraTarget
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!4 &1262072125491596160
|
||||
Transform:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 9012401119129405183}
|
||||
serializedVersion: 2
|
||||
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
||||
m_LocalPosition: {x: 0, y: 0.226, z: -0.155}
|
||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||
m_ConstrainProportionsScale: 0
|
||||
m_Children: []
|
||||
m_Father: {fileID: 7343299364369393213}
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
--- !u!1001 &4502887663618702391
|
||||
PrefabInstance:
|
||||
m_ObjectHideFlags: 0
|
||||
serializedVersion: 2
|
||||
m_Modification:
|
||||
serializedVersion: 3
|
||||
m_TransformParent: {fileID: 7343299364369393213}
|
||||
m_Modifications:
|
||||
- target: {fileID: 180557533655662575, guid: 930b7a19d446f4b4c9c810e37e84e625, type: 3}
|
||||
propertyPath: m_Name
|
||||
value: WhiteHand
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 705561775665358165, guid: 930b7a19d446f4b4c9c810e37e84e625, type: 3}
|
||||
propertyPath: m_LocalPosition.x
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 705561775665358165, guid: 930b7a19d446f4b4c9c810e37e84e625, type: 3}
|
||||
propertyPath: m_LocalPosition.y
|
||||
value: 0.1
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 705561775665358165, guid: 930b7a19d446f4b4c9c810e37e84e625, type: 3}
|
||||
propertyPath: m_LocalPosition.z
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 705561775665358165, guid: 930b7a19d446f4b4c9c810e37e84e625, type: 3}
|
||||
propertyPath: m_LocalRotation.w
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 705561775665358165, guid: 930b7a19d446f4b4c9c810e37e84e625, type: 3}
|
||||
propertyPath: m_LocalRotation.x
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 705561775665358165, guid: 930b7a19d446f4b4c9c810e37e84e625, type: 3}
|
||||
propertyPath: m_LocalRotation.y
|
||||
value: 1
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 705561775665358165, guid: 930b7a19d446f4b4c9c810e37e84e625, type: 3}
|
||||
propertyPath: m_LocalRotation.z
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 705561775665358165, guid: 930b7a19d446f4b4c9c810e37e84e625, type: 3}
|
||||
propertyPath: m_LocalEulerAnglesHint.x
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 705561775665358165, guid: 930b7a19d446f4b4c9c810e37e84e625, type: 3}
|
||||
propertyPath: m_LocalEulerAnglesHint.y
|
||||
value: 180
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 705561775665358165, guid: 930b7a19d446f4b4c9c810e37e84e625, type: 3}
|
||||
propertyPath: m_LocalEulerAnglesHint.z
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
m_RemovedComponents: []
|
||||
m_RemovedGameObjects: []
|
||||
m_AddedGameObjects: []
|
||||
m_AddedComponents:
|
||||
- targetCorrespondingSourceObject: {fileID: 1338243545944059599, guid: 930b7a19d446f4b4c9c810e37e84e625, type: 3}
|
||||
insertIndex: -1
|
||||
addedObject: {fileID: 1165829002027726284}
|
||||
m_SourcePrefab: {fileID: 100100000, guid: 930b7a19d446f4b4c9c810e37e84e625, type: 3}
|
||||
--- !u!1 &3237838625342182136 stripped
|
||||
GameObject:
|
||||
m_CorrespondingSourceObject: {fileID: 1338243545944059599, guid: 930b7a19d446f4b4c9c810e37e84e625, type: 3}
|
||||
m_PrefabInstance: {fileID: 4502887663618702391}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
--- !u!114 &1165829002027726284
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 3237838625342182136}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: 5fc799adb27d5ea45990b5522b75ddda, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier: Assembly-CSharp::MeshPainter
|
||||
brushShader: {fileID: 0}
|
||||
dilateShader: {fileID: 0}
|
||||
packMsShader: {fileID: 0}
|
||||
persistPaint: 1
|
||||
saveId:
|
||||
pipette: 0
|
||||
spray: 0
|
||||
sprayDots: 24
|
||||
sprayDotSizeMin: 0.05
|
||||
sprayDotSizeMax: 0.18
|
||||
sprayDotAlphaMin: 0.25
|
||||
sprayDotAlphaMax: 1
|
||||
useGpu: 1
|
||||
paintAlbedo: 1
|
||||
paintMetallicSmoothness: 0
|
||||
paintOcclusion: 0
|
||||
paintEmission: 0
|
||||
brushColor: {r: 0.6, g: 0.6, b: 1, a: 1}
|
||||
metallic: 1
|
||||
smoothness: 1
|
||||
metallicSmoothnessOpacity: 1
|
||||
occlusion: 1
|
||||
occlusionOpacity: 1
|
||||
emissionColor: {r: 1, g: 0.6, b: 0, a: 1}
|
||||
emissionIntensity: 200
|
||||
brushSize: 100
|
||||
brushMasks:
|
||||
- {fileID: 10300, guid: 0000000000000000f000000000000000, type: 0}
|
||||
- {fileID: 10912, guid: 0000000000000000f000000000000000, type: 0}
|
||||
activeBrushIndex: 0
|
||||
brushAlignment: 0
|
||||
brushRotation: 0
|
||||
paintOnMoveOnly: 1
|
||||
paintInterval: 0
|
||||
previewMode: 2
|
||||
previewOpacity: 1
|
||||
textureSize: 1024
|
||||
baseColor: {r: 0.8, g: 0.8, b: 0.8, a: 1}
|
||||
paddingTexels: 2
|
||||
paintCamera: {fileID: 0}
|
||||
updateColliderEveryFrame: 1
|
||||
previewShader: {fileID: 0}
|
||||
--- !u!4 &4014907164611811682 stripped
|
||||
Transform:
|
||||
m_CorrespondingSourceObject: {fileID: 705561775665358165, guid: 930b7a19d446f4b4c9c810e37e84e625, type: 3}
|
||||
m_PrefabInstance: {fileID: 4502887663618702391}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b3a1e0eb07937fa418c99504f882bee2
|
||||
PrefabImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Reference in new issue
Block a user