Completed all projectiles work
This commit is contained in:
parent
7d16edf73f
commit
962128fb7f
1
Assets/Resources/PerformanceTestRunInfo.json
Normal file
1
Assets/Resources/PerformanceTestRunInfo.json
Normal file
@ -0,0 +1 @@
|
||||
{"TestSuite":"","Date":0,"Player":{"Development":false,"ScreenWidth":0,"ScreenHeight":0,"ScreenRefreshRate":0,"Fullscreen":false,"Vsync":0,"AntiAliasing":0,"Batchmode":false,"RenderThreadingMode":"MultiThreaded","GpuSkinning":false,"Platform":"","ColorSpace":"","AnisotropicFiltering":"","BlendWeights":"","GraphicsApi":"","ScriptingBackend":"IL2CPP","AndroidTargetSdkVersion":"AndroidApiLevelAuto","AndroidBuildSystem":"Gradle","BuildTarget":"WebGL","StereoRenderingPath":"MultiPass"},"Hardware":{"OperatingSystem":"","DeviceModel":"","DeviceName":"","ProcessorType":"","ProcessorCount":0,"GraphicsDeviceName":"","SystemMemorySizeMB":0},"Editor":{"Version":"6000.0.56f1","Branch":"6000.0/staging","Changeset":"9c7b5e468860","Date":1754996063},"Dependencies":["com.unity.collab-proxy@2.9.2","com.unity.feature.2d@2.0.1","com.unity.ide.rider@3.0.36","com.unity.ide.visualstudio@2.0.23","com.unity.inputsystem@1.14.2","com.unity.multiplayer.center@1.0.0","com.unity.render-pipelines.universal@17.0.4","com.unity.test-framework@1.5.1","com.unity.timeline@1.8.9","com.unity.ugui@2.0.0","com.unity.visualscripting@1.9.7","com.unity.modules.accessibility@1.0.0","com.unity.modules.ai@1.0.0","com.unity.modules.androidjni@1.0.0","com.unity.modules.animation@1.0.0","com.unity.modules.assetbundle@1.0.0","com.unity.modules.audio@1.0.0","com.unity.modules.cloth@1.0.0","com.unity.modules.director@1.0.0","com.unity.modules.imageconversion@1.0.0","com.unity.modules.imgui@1.0.0","com.unity.modules.jsonserialize@1.0.0","com.unity.modules.particlesystem@1.0.0","com.unity.modules.physics@1.0.0","com.unity.modules.physics2d@1.0.0","com.unity.modules.screencapture@1.0.0","com.unity.modules.terrain@1.0.0","com.unity.modules.terrainphysics@1.0.0","com.unity.modules.tilemap@1.0.0","com.unity.modules.ui@1.0.0","com.unity.modules.uielements@1.0.0","com.unity.modules.umbra@1.0.0","com.unity.modules.unityanalytics@1.0.0","com.unity.modules.unitywebrequest@1.0.0","com.unity.modules.unitywebrequestassetbundle@1.0.0","com.unity.modules.unitywebrequestaudio@1.0.0","com.unity.modules.unitywebrequesttexture@1.0.0","com.unity.modules.unitywebrequestwww@1.0.0","com.unity.modules.vehicles@1.0.0","com.unity.modules.video@1.0.0","com.unity.modules.vr@1.0.0","com.unity.modules.wind@1.0.0","com.unity.modules.xr@1.0.0","com.unity.modules.subsystems@1.0.0","com.unity.modules.hierarchycore@1.0.0","com.unity.ext.nunit@2.0.5","com.unity.render-pipelines.core@17.0.4","com.unity.shadergraph@17.0.4","com.unity.render-pipelines.universal-config@17.0.3","com.unity.2d.animation@10.2.1","com.unity.2d.pixel-perfect@5.0.3","com.unity.2d.psdimporter@9.1.0","com.unity.2d.sprite@1.0.0","com.unity.2d.spriteshape@10.0.7","com.unity.2d.tilemap@1.0.0","com.unity.2d.tilemap.extras@4.1.0","com.unity.2d.aseprite@1.1.10","com.unity.searcher@4.9.3","com.unity.burst@1.8.24","com.unity.mathematics@1.3.2","com.unity.collections@2.5.1","com.unity.rendering.light-transport@1.0.1","com.unity.2d.common@9.1.1","com.unity.nuget.mono-cecil@1.11.4","com.unity.test-framework.performance@3.1.0"],"Results":[]}
|
||||
7
Assets/Resources/PerformanceTestRunInfo.json.meta
Normal file
7
Assets/Resources/PerformanceTestRunInfo.json.meta
Normal file
@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3f79429828f617f4e928d4bfd1a938e2
|
||||
TextScriptImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
1
Assets/Resources/PerformanceTestRunSettings.json
Normal file
1
Assets/Resources/PerformanceTestRunSettings.json
Normal file
@ -0,0 +1 @@
|
||||
{"MeasurementCount":-1}
|
||||
7
Assets/Resources/PerformanceTestRunSettings.json.meta
Normal file
7
Assets/Resources/PerformanceTestRunSettings.json.meta
Normal file
@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 91efd83a093a02a4291e2c5043f20400
|
||||
TextScriptImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -11,7 +11,7 @@ GameObject:
|
||||
- component: {fileID: 1452460312376183192}
|
||||
- component: {fileID: -640855425046532091}
|
||||
- component: {fileID: 8375585699851212105}
|
||||
- component: {fileID: -7990430535451479416}
|
||||
- component: {fileID: 5633092123120389871}
|
||||
m_Layer: 0
|
||||
m_Name: PickableProjectile
|
||||
m_TagString: Projectile
|
||||
@ -47,7 +47,7 @@ Rigidbody2D:
|
||||
m_Simulated: 1
|
||||
m_UseFullKinematicContacts: 0
|
||||
m_UseAutoMass: 0
|
||||
m_Mass: 1
|
||||
m_Mass: 5
|
||||
m_LinearDamping: 0
|
||||
m_AngularDamping: 0.05
|
||||
m_GravityScale: 1
|
||||
@ -98,7 +98,7 @@ CircleCollider2D:
|
||||
m_CompositeOrder: 0
|
||||
m_Offset: {x: 0, y: 0}
|
||||
m_Radius: 0.5
|
||||
--- !u!114 &-7990430535451479416
|
||||
--- !u!114 &5633092123120389871
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
@ -110,31 +110,36 @@ MonoBehaviour:
|
||||
m_Script: {fileID: 11500000, guid: 5bf80b3f74c7fe04e8064ebca52b7ad4, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
initialSpeed: 20
|
||||
initialSpeed: 25
|
||||
maxLifetime: 5
|
||||
alignRotationToVelocity: 1
|
||||
knockback: 0
|
||||
hitLayers:
|
||||
serializedVersion: 2
|
||||
m_Bits: 0
|
||||
m_Bits: 4294967295
|
||||
maxPierce: 0
|
||||
useGravity: 1
|
||||
gravityScale: 3
|
||||
gravityScale: 1
|
||||
owner: {fileID: 0}
|
||||
hitVfxPrefab: {fileID: 0}
|
||||
hitSfx: {fileID: 0}
|
||||
sfxVolume: 1
|
||||
heldLocalOffset: {x: 0.25, y: 0.1, z: 0}
|
||||
ignoreOwnerTimeOnThrow: 0.15
|
||||
snapExactlyToAttachPoint: 1
|
||||
ignoreOwnerTimeOnThrow: 0.25
|
||||
attachPointChildName: HandPoint
|
||||
sleepVelocity: 0.05
|
||||
lockWhenLanded: 1
|
||||
maxBounces: 20
|
||||
minBounceSpeed: 0.8
|
||||
maxBounces: 100
|
||||
minBounceSpeed: 8
|
||||
restitution: 0.6
|
||||
tangentDamping: 0.85
|
||||
groundUpTolerance: 0.25
|
||||
stickDelayAfterImpact: 0.03
|
||||
recallStartDistance: 10
|
||||
recallArriveDistance: 1.4
|
||||
recallMaxSpeed: 16
|
||||
recallAcceleration: 60
|
||||
drawGizmos: 1
|
||||
gizmoColor: {r: 0.2, g: 0.8, b: 1, a: 0.35}
|
||||
--- !u!1 &7253843866260996112
|
||||
|
||||
@ -32,6 +32,37 @@ Transform:
|
||||
- {fileID: 6550761235546795890}
|
||||
m_Father: {fileID: 6550761235875199946}
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
--- !u!1 &5503244841086142080
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
serializedVersion: 6
|
||||
m_Component:
|
||||
- component: {fileID: 1082696284330290386}
|
||||
m_Layer: 0
|
||||
m_Name: HandPoint
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!4 &1082696284330290386
|
||||
Transform:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 5503244841086142080}
|
||||
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: 6550761234898366363}
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
--- !u!1 &6550761233853193377
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
@ -1841,6 +1872,7 @@ Transform:
|
||||
m_ConstrainProportionsScale: 0
|
||||
m_Children:
|
||||
- {fileID: 6550761235822222727}
|
||||
- {fileID: 1082696284330290386}
|
||||
m_Father: {fileID: 6550761235013283179}
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: -25.939}
|
||||
--- !u!212 &6550761234898366361
|
||||
@ -1910,9 +1942,9 @@ MonoBehaviour:
|
||||
m_Script: {fileID: 11500000, guid: 57c008f954fe54a8bb972de1018a2cb8, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
m_RootBone: {fileID: 6550761235822222727}
|
||||
m_RootBone: {fileID: 6550761234898366363}
|
||||
m_BoneTransforms:
|
||||
- {fileID: 6550761235822222727}
|
||||
- {fileID: 0}
|
||||
m_Bounds:
|
||||
m_Center: {x: 0.00043550134, y: -0.000074744225, z: 0}
|
||||
m_Extent: {x: 0.376185, y: 0.435875, z: 0}
|
||||
@ -2656,7 +2688,6 @@ MonoBehaviour:
|
||||
attachPoint: {fileID: 6550761234898366363}
|
||||
actionKey: 102
|
||||
throwSpeed: 20
|
||||
pickupRadius: 1.2
|
||||
--- !u!1 &6550761235546795891
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
|
||||
@ -60189,63 +60189,6 @@ SpriteRenderer:
|
||||
m_WasSpriteAssigned: 1
|
||||
m_MaskInteraction: 0
|
||||
m_SpriteSortPoint: 0
|
||||
--- !u!1001 &1409395841
|
||||
PrefabInstance:
|
||||
m_ObjectHideFlags: 0
|
||||
serializedVersion: 2
|
||||
m_Modification:
|
||||
serializedVersion: 3
|
||||
m_TransformParent: {fileID: 0}
|
||||
m_Modifications:
|
||||
- target: {fileID: 1452460312376183192, guid: 7fd3a37dc702ece42b51e5867473f0ff, type: 3}
|
||||
propertyPath: m_LocalPosition.x
|
||||
value: -3.1233063
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 1452460312376183192, guid: 7fd3a37dc702ece42b51e5867473f0ff, type: 3}
|
||||
propertyPath: m_LocalPosition.y
|
||||
value: -19.482407
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 1452460312376183192, guid: 7fd3a37dc702ece42b51e5867473f0ff, type: 3}
|
||||
propertyPath: m_LocalPosition.z
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 1452460312376183192, guid: 7fd3a37dc702ece42b51e5867473f0ff, type: 3}
|
||||
propertyPath: m_LocalRotation.w
|
||||
value: 1
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 1452460312376183192, guid: 7fd3a37dc702ece42b51e5867473f0ff, type: 3}
|
||||
propertyPath: m_LocalRotation.x
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 1452460312376183192, guid: 7fd3a37dc702ece42b51e5867473f0ff, type: 3}
|
||||
propertyPath: m_LocalRotation.y
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 1452460312376183192, guid: 7fd3a37dc702ece42b51e5867473f0ff, type: 3}
|
||||
propertyPath: m_LocalRotation.z
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 1452460312376183192, guid: 7fd3a37dc702ece42b51e5867473f0ff, type: 3}
|
||||
propertyPath: m_LocalEulerAnglesHint.x
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 1452460312376183192, guid: 7fd3a37dc702ece42b51e5867473f0ff, type: 3}
|
||||
propertyPath: m_LocalEulerAnglesHint.y
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 1452460312376183192, guid: 7fd3a37dc702ece42b51e5867473f0ff, type: 3}
|
||||
propertyPath: m_LocalEulerAnglesHint.z
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 5993946430821065449, guid: 7fd3a37dc702ece42b51e5867473f0ff, type: 3}
|
||||
propertyPath: m_Name
|
||||
value: PickableProjectile
|
||||
objectReference: {fileID: 0}
|
||||
m_RemovedComponents: []
|
||||
m_RemovedGameObjects: []
|
||||
m_AddedGameObjects: []
|
||||
m_AddedComponents: []
|
||||
m_SourcePrefab: {fileID: 100100000, guid: 7fd3a37dc702ece42b51e5867473f0ff, type: 3}
|
||||
--- !u!1001 &1503664770
|
||||
PrefabInstance:
|
||||
m_ObjectHideFlags: 0
|
||||
@ -60891,6 +60834,63 @@ Transform:
|
||||
- {fileID: 1604648029}
|
||||
m_Father: {fileID: 0}
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
--- !u!1001 &1968702169
|
||||
PrefabInstance:
|
||||
m_ObjectHideFlags: 0
|
||||
serializedVersion: 2
|
||||
m_Modification:
|
||||
serializedVersion: 3
|
||||
m_TransformParent: {fileID: 0}
|
||||
m_Modifications:
|
||||
- target: {fileID: 1452460312376183192, guid: 7fd3a37dc702ece42b51e5867473f0ff, type: 3}
|
||||
propertyPath: m_LocalPosition.x
|
||||
value: 4.7835865
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 1452460312376183192, guid: 7fd3a37dc702ece42b51e5867473f0ff, type: 3}
|
||||
propertyPath: m_LocalPosition.y
|
||||
value: 2.5
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 1452460312376183192, guid: 7fd3a37dc702ece42b51e5867473f0ff, type: 3}
|
||||
propertyPath: m_LocalPosition.z
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 1452460312376183192, guid: 7fd3a37dc702ece42b51e5867473f0ff, type: 3}
|
||||
propertyPath: m_LocalRotation.w
|
||||
value: 1
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 1452460312376183192, guid: 7fd3a37dc702ece42b51e5867473f0ff, type: 3}
|
||||
propertyPath: m_LocalRotation.x
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 1452460312376183192, guid: 7fd3a37dc702ece42b51e5867473f0ff, type: 3}
|
||||
propertyPath: m_LocalRotation.y
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 1452460312376183192, guid: 7fd3a37dc702ece42b51e5867473f0ff, type: 3}
|
||||
propertyPath: m_LocalRotation.z
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 1452460312376183192, guid: 7fd3a37dc702ece42b51e5867473f0ff, type: 3}
|
||||
propertyPath: m_LocalEulerAnglesHint.x
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 1452460312376183192, guid: 7fd3a37dc702ece42b51e5867473f0ff, type: 3}
|
||||
propertyPath: m_LocalEulerAnglesHint.y
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 1452460312376183192, guid: 7fd3a37dc702ece42b51e5867473f0ff, type: 3}
|
||||
propertyPath: m_LocalEulerAnglesHint.z
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 5993946430821065449, guid: 7fd3a37dc702ece42b51e5867473f0ff, type: 3}
|
||||
propertyPath: m_Name
|
||||
value: PickableProjectile
|
||||
objectReference: {fileID: 0}
|
||||
m_RemovedComponents: []
|
||||
m_RemovedGameObjects: []
|
||||
m_AddedGameObjects: []
|
||||
m_AddedComponents: []
|
||||
m_SourcePrefab: {fileID: 100100000, guid: 7fd3a37dc702ece42b51e5867473f0ff, type: 3}
|
||||
--- !u!1001 &2013056424
|
||||
PrefabInstance:
|
||||
m_ObjectHideFlags: 0
|
||||
@ -61107,4 +61107,4 @@ SceneRoots:
|
||||
- {fileID: 872032055}
|
||||
- {fileID: 2041263421}
|
||||
- {fileID: 2013056424}
|
||||
- {fileID: 1409395841}
|
||||
- {fileID: 1968702169}
|
||||
|
||||
@ -1,5 +1,4 @@
|
||||
using Projectiles2D;
|
||||
using UnityEngine;
|
||||
using UnityEngine;
|
||||
|
||||
public class PlayerFireScript : MonoBehaviour
|
||||
{
|
||||
@ -11,74 +10,65 @@ public class PlayerFireScript : MonoBehaviour
|
||||
public Transform attachPoint;
|
||||
public KeyCode actionKey = KeyCode.F;
|
||||
public float throwSpeed = 20f;
|
||||
public float pickupRadius = 1.2f;
|
||||
|
||||
private PickableProjectile P => PickableProjectile.Instance;
|
||||
private PickableProjectile pickableProj;
|
||||
|
||||
void Awake()
|
||||
{
|
||||
if (!attachPoint)
|
||||
{
|
||||
var hand = transform.Find("HandPoint");
|
||||
if (hand) attachPoint = hand;
|
||||
}
|
||||
attachPoint = FindDeepChild(transform, "HandPoint");
|
||||
|
||||
if (!attachPoint)
|
||||
Debug.LogWarning("PlayerFireScript: attachPoint не задан и HandPoint не найден. Будет использован корень игрока.");
|
||||
}
|
||||
|
||||
void Update()
|
||||
void Update()
|
||||
{
|
||||
var proj = P;
|
||||
|
||||
if (proj != null && proj.CurrentState != PickableProjectile.State.Held)
|
||||
{
|
||||
Vector3 grabFrom = attachPoint ? attachPoint.position : transform.position;
|
||||
float dist = Vector2.Distance(proj.transform.position, grabFrom);
|
||||
|
||||
if (dist <= pickupRadius)
|
||||
{
|
||||
proj.TryPickup(gameObject, attachPoint);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (!Input.GetKeyDown(actionKey)) return;
|
||||
|
||||
proj = P;
|
||||
if (pickableProj == null)
|
||||
pickableProj = PickableProjectile.Instance;
|
||||
|
||||
if (proj == null)
|
||||
if (pickableProj == null)
|
||||
{
|
||||
if (!spawnIfMissing || projectilePrefab == null)
|
||||
{
|
||||
Debug.Log("FireScript2D: projectile missing; set spawnIfMissing=true and assign projectilePrefab.");
|
||||
Debug.Log("PlayerFireScript: projectile missing; enable spawnIfMissing and assign projectilePrefab.");
|
||||
return;
|
||||
}
|
||||
|
||||
Vector3 spawnPos = attachPoint ? attachPoint.position : transform.position;
|
||||
proj = Instantiate(projectilePrefab, spawnPos, Quaternion.identity);
|
||||
proj.TryPickup(gameObject, attachPoint);
|
||||
pickableProj = Instantiate(projectilePrefab, spawnPos, Quaternion.identity);
|
||||
pickableProj.TryPickup(gameObject, attachPoint);
|
||||
return;
|
||||
}
|
||||
|
||||
if (proj.CurrentState == PickableProjectile.State.Held && proj.owner == gameObject)
|
||||
// Бросок
|
||||
if (pickableProj.CurrentState == PickableProjectile.State.Held && pickableProj.owner == gameObject)
|
||||
{
|
||||
float sx = transform.localScale.x;
|
||||
float facing = Mathf.Sign(sx == 0 ? 1 : sx);
|
||||
Vector2 dir = facing > 0 ? Vector2.right : Vector2.left;
|
||||
Vector2 launchPos = (Vector2)transform.position + new Vector2(1.4f * facing, 0f);
|
||||
proj.transform.localScale = new Vector3(-facing * proj.transform.localScale.x, proj.transform.localScale.y, proj.transform.localScale.z);
|
||||
proj.transform.position = launchPos;
|
||||
|
||||
proj.Launch(dir, throwSpeed, gameObject);
|
||||
return;
|
||||
var s = pickableProj.transform.localScale;
|
||||
pickableProj.transform.localScale = new Vector3(Mathf.Abs(s.x) * -facing, s.y, s.z);
|
||||
|
||||
pickableProj.transform.position = launchPos;
|
||||
pickableProj.Launch(dir, throwSpeed, gameObject);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#if UNITY_EDITOR
|
||||
void OnDrawGizmosSelected()
|
||||
public void BindProjectile(PickableProjectile proj) => pickableProj = proj;
|
||||
|
||||
private Transform FindDeepChild(Transform parent, string name)
|
||||
{
|
||||
Gizmos.color = new Color(0.2f, 0.8f, 1f, 0.35f);
|
||||
Vector3 center = attachPoint ? attachPoint.position : transform.position;
|
||||
Gizmos.DrawWireSphere(center, pickupRadius);
|
||||
foreach (Transform child in parent)
|
||||
{
|
||||
if (child.name == name) return child;
|
||||
var r = FindDeepChild(child, name);
|
||||
if (r) return r;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
@ -9,7 +9,7 @@ public class EnemyController : MonoBehaviour
|
||||
public float moveSpeed = 3f;
|
||||
public float acceleration = 10f;
|
||||
|
||||
private LayerMask obstacleMask;
|
||||
private LayerMask obstacleMask = ~0;
|
||||
private Animator animator;
|
||||
private Rigidbody2D rb;
|
||||
private Vector2 targetVelocity = Vector2.zero;
|
||||
|
||||
@ -16,7 +16,8 @@ public class GameManager : MonoBehaviour
|
||||
public int lives { get; private set; } = 3;
|
||||
public int coins { get; private set; } = 0;
|
||||
|
||||
public GameObject playerObj;
|
||||
public GameObject playerObj { get; private set; }
|
||||
|
||||
[SerializeField] private GameObject playerPrefab;
|
||||
[SerializeField] private string playerPrefabResourcePath = "Prefabs/Player";
|
||||
|
||||
@ -25,6 +26,8 @@ public class GameManager : MonoBehaviour
|
||||
private void OnEnable() => SceneManager.sceneLoaded += OnSceneLoaded;
|
||||
private void OnDisable() => SceneManager.sceneLoaded -= OnSceneLoaded;
|
||||
|
||||
public event Action<GameObject> PlayerSpawned;
|
||||
|
||||
public event Action<int> CoinsChanged;
|
||||
|
||||
[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.BeforeSceneLoad)]
|
||||
@ -117,6 +120,7 @@ public class GameManager : MonoBehaviour
|
||||
{
|
||||
SceneManager.LoadScene("Level UI", LoadSceneMode.Additive);
|
||||
}
|
||||
|
||||
else _shouldSpawnPlayer = false;
|
||||
}
|
||||
|
||||
@ -140,6 +144,8 @@ public class GameManager : MonoBehaviour
|
||||
|
||||
playerObj = Instantiate(prefab, pos, rot);
|
||||
SceneManager.MoveGameObjectToScene(playerObj, SceneManager.GetActiveScene());
|
||||
|
||||
PlayerSpawned?.Invoke(playerObj);
|
||||
}
|
||||
|
||||
public void NextLevel()
|
||||
|
||||
@ -1,5 +1,4 @@
|
||||
using UnityEngine;
|
||||
using UnityEngine.SceneManagement;
|
||||
|
||||
[DisallowMultipleComponent]
|
||||
[RequireComponent(typeof(Rigidbody2D))]
|
||||
@ -13,6 +12,7 @@ public class PickableProjectile : BasicProjectile
|
||||
|
||||
[Header("Pickup/Attach")]
|
||||
public Vector3 heldLocalOffset = new(0.25f, 0.1f, 0f);
|
||||
public bool snapExactlyToAttachPoint = true;
|
||||
public float ignoreOwnerTimeOnThrow = 0.25f;
|
||||
public string attachPointChildName = "HandPoint";
|
||||
|
||||
@ -21,47 +21,30 @@ public class PickableProjectile : BasicProjectile
|
||||
public bool lockWhenLanded = true;
|
||||
|
||||
[Header("Bouncing")]
|
||||
[Tooltip("Максимум отскоков прежде чем лечь на землю.")]
|
||||
public int maxBounces = 3;
|
||||
[Tooltip("Минимальная скорость для отскока.")]
|
||||
public float minBounceSpeed = 0.8f;
|
||||
[Tooltip("Коэффициент упругости (0..1).")]
|
||||
[Range(0f, 1f)] public float restitution = 0.6f;
|
||||
[Tooltip("Демпфирование вдоль поверхности (0..1), меньше — сильнее гасит скольжение.")]
|
||||
[Range(0f, 1f)] public float tangentDamping = 0.85f;
|
||||
[Tooltip("Насколько «вверх» должна смотреть средняя нормаль, чтобы считать поверхность землёй.")]
|
||||
[Range(0f, 1f)] public float groundUpTolerance = 0.25f;
|
||||
[Tooltip("Маленькая пауза, чтобы не прилипнуть в кадр столкновения.")]
|
||||
public float stickDelayAfterImpact = 0.03f;
|
||||
|
||||
[Header("Persistence / Recall")]
|
||||
[Tooltip("Сохранять снаряд между сценами.")]
|
||||
public bool persistAcrossScenes = true;
|
||||
[Tooltip("Если перед загрузкой новой сцены снаряд был в руке — автоматически прицепиться к игроку на новой сцене.")]
|
||||
public bool reattachIfWasHeldOnLoad = true;
|
||||
|
||||
[Tooltip("Старт возврата, если дальше этой дистанции от точки руки.")]
|
||||
public float recallStartDistance = 8f;
|
||||
[Tooltip("На этой дистанции от руки считаем, что прилетел и подбираем.")]
|
||||
public float recallArriveDistance = 1.4f;
|
||||
[Tooltip("Максимальная скорость «магнита».")]
|
||||
public float recallArriveDistance = 1f;
|
||||
public float recallMaxSpeed = 16f;
|
||||
[Tooltip("Ускорение «магнита».")]
|
||||
public float recallAcceleration = 60f;
|
||||
|
||||
[Header("Gizmos")]
|
||||
public bool drawGizmos;
|
||||
public Color gizmoColor = new Color(0.2f, 0.8f, 1f, 0.35f);
|
||||
|
||||
private GameObject holder;
|
||||
private Transform holderAttachPoint;
|
||||
|
||||
private int bounceCounter = 0;
|
||||
private float lastImpactTime = -999f;
|
||||
private Vector3 baseLocalScale = Vector3.one;
|
||||
|
||||
// «Когда-либо был в руке» — разрешает бумеранг
|
||||
private bool hadBeenHeld = false;
|
||||
// Запоминаем последнего игрока для возврата
|
||||
private GameObject lastKnownHolder;
|
||||
|
||||
protected override void Awake()
|
||||
@ -73,114 +56,52 @@ public class PickableProjectile : BasicProjectile
|
||||
Destroy(gameObject);
|
||||
return;
|
||||
}
|
||||
|
||||
Instance = this;
|
||||
|
||||
if (persistAcrossScenes)
|
||||
DontDestroyOnLoad(gameObject);
|
||||
|
||||
SceneManager.sceneLoaded += OnSceneLoaded;
|
||||
|
||||
rb.collisionDetectionMode = CollisionDetectionMode2D.Continuous;
|
||||
col.isTrigger = false;
|
||||
|
||||
BecomeGrounded(null);
|
||||
}
|
||||
|
||||
private void OnDestroy()
|
||||
{
|
||||
if (Instance == this) Instance = null;
|
||||
SceneManager.sceneLoaded -= OnSceneLoaded;
|
||||
}
|
||||
|
||||
private void OnSceneLoaded(Scene scene, LoadSceneMode mode)
|
||||
{
|
||||
Debug.Log("OnSceneLoaded");
|
||||
Debug.Log($"Owner: {owner}");
|
||||
Debug.Log($"LastKnownHolder: {lastKnownHolder}");
|
||||
if (!reattachIfWasHeldOnLoad) return;
|
||||
|
||||
// Если до загрузки мы были в руке — прицепляемся к игроку на новой сцене
|
||||
if (CurrentState == State.Held || (hadBeenHeld && owner != null))
|
||||
private void Start()
|
||||
{
|
||||
rb.collisionDetectionMode = CollisionDetectionMode2D.Continuous;
|
||||
col.isTrigger = false;
|
||||
|
||||
if (CurrentState != State.Held)
|
||||
BecomeGrounded(null);
|
||||
}
|
||||
|
||||
protected override void FixedUpdate()
|
||||
{
|
||||
base.FixedUpdate();
|
||||
|
||||
if (!lockWhenLanded && CurrentState == State.Airborne)
|
||||
{
|
||||
var playerGo =
|
||||
(GameManager.Instance && GameManager.Instance.playerObj) ?
|
||||
GameManager.Instance.playerObj :
|
||||
GameObject.FindWithTag("Player");
|
||||
|
||||
Debug.Log($"PlayerObj: {playerGo}");
|
||||
|
||||
if (!playerGo) return;
|
||||
|
||||
var attach = FindAttachPointOn(playerGo) ?? playerGo.transform;
|
||||
|
||||
transform.SetParent(null, true);
|
||||
TryPickup(playerGo, attach);
|
||||
if (rb.linearVelocity.sqrMagnitude < (sleepVelocity * sleepVelocity))
|
||||
BecomeGrounded(null);
|
||||
}
|
||||
}
|
||||
|
||||
public bool TryPickup(GameObject newHolder, Transform optionalAttachPoint = null)
|
||||
{
|
||||
if (CurrentState == State.Held) return true;
|
||||
|
||||
holder = newHolder;
|
||||
lastKnownHolder = newHolder;
|
||||
|
||||
holderAttachPoint = optionalAttachPoint ?? FindAttachPointOn(holder);
|
||||
if (holderAttachPoint == null) holderAttachPoint = holder.transform;
|
||||
|
||||
rb.linearVelocity = Vector2.zero;
|
||||
rb.angularVelocity = 0f;
|
||||
rb.bodyType = RigidbodyType2D.Kinematic;
|
||||
col.enabled = false;
|
||||
|
||||
transform.SetParent(holderAttachPoint, worldPositionStays: false);
|
||||
transform.localPosition = heldLocalOffset;
|
||||
transform.localRotation = Quaternion.identity;
|
||||
transform.localScale = Vector3.one * 2; // оставляю как у тебя
|
||||
|
||||
// Игнор коллизии владельца нужен при броске, не при «магните»
|
||||
StartCoroutine(IgnoreOwnerTemporarily(holder, ignoreOwnerTimeOnThrow));
|
||||
|
||||
CurrentState = State.Held;
|
||||
launched = false;
|
||||
owner = holder;
|
||||
|
||||
hadBeenHeld = true; // разрешаем бумеранг в будущем
|
||||
return true;
|
||||
}
|
||||
|
||||
public void Launch(Vector2 direction, float speed, GameObject throwOwner = null)
|
||||
{
|
||||
if (CurrentState == State.Held)
|
||||
transform.SetParent(null, true);
|
||||
|
||||
holder = throwOwner;
|
||||
lastKnownHolder = throwOwner;
|
||||
holderAttachPoint = null;
|
||||
|
||||
rb.bodyType = RigidbodyType2D.Dynamic;
|
||||
col.enabled = true;
|
||||
|
||||
launched = true;
|
||||
owner = throwOwner;
|
||||
|
||||
Vector2 dir = direction.sqrMagnitude > 0.0001f ? direction.normalized : Vector2.right;
|
||||
float finalSpeed = (speed > 0f) ? speed : initialSpeed;
|
||||
|
||||
rb.linearVelocity = Vector2.zero;
|
||||
rb.angularVelocity = 0f;
|
||||
rb.AddForce(dir * finalSpeed * rb.mass, ForceMode2D.Impulse);
|
||||
transform.right = dir;
|
||||
|
||||
if (throwOwner != null && ignoreOwnerTimeOnThrow > 0f)
|
||||
StartCoroutine(IgnoreOwnerTemporarily(throwOwner, ignoreOwnerTimeOnThrow));
|
||||
|
||||
CurrentState = State.Airborne;
|
||||
bounceCounter = 0;
|
||||
// Бумеранг только если снаряд когда-то уже был в руке
|
||||
if (hadBeenHeld && CurrentState != State.Held)
|
||||
HandleRecallToPlayer();
|
||||
}
|
||||
|
||||
protected override void OnCollisionEnter2D(Collision2D collision)
|
||||
{
|
||||
var otherRb = collision.rigidbody ? collision.rigidbody : collision.otherRigidbody;
|
||||
var otherGo = (collision.collider ? collision.collider.attachedRigidbody?.gameObject : null)
|
||||
?? otherRb?.gameObject
|
||||
?? collision.gameObject;
|
||||
|
||||
if (otherGo && otherGo.CompareTag("Player") && CurrentState != State.Held)
|
||||
{
|
||||
if (TryPickup(otherGo)) return;
|
||||
}
|
||||
|
||||
base.OnCollisionEnter2D(collision);
|
||||
|
||||
if (CurrentState == State.Airborne)
|
||||
@ -195,6 +116,83 @@ public class PickableProjectile : BasicProjectile
|
||||
}
|
||||
}
|
||||
|
||||
public bool TryPickup(GameObject newHolder, Transform optionalAttachPoint = null)
|
||||
{
|
||||
if (CurrentState == State.Held) return true;
|
||||
|
||||
owner = newHolder;
|
||||
lastKnownHolder = newHolder;
|
||||
|
||||
holderAttachPoint = optionalAttachPoint ?? FindAttachPoint(newHolder);
|
||||
var fireScript = newHolder.GetComponent<PlayerFireScript>();
|
||||
if (holderAttachPoint == null && fireScript != null)
|
||||
holderAttachPoint = fireScript.attachPoint;
|
||||
if (holderAttachPoint == null)
|
||||
holderAttachPoint = newHolder.transform;
|
||||
|
||||
rb.linearVelocity = Vector2.zero;
|
||||
rb.angularVelocity = 0f;
|
||||
rb.bodyType = RigidbodyType2D.Kinematic;
|
||||
col.enabled = false;
|
||||
|
||||
transform.SetParent(holderAttachPoint, worldPositionStays: true);
|
||||
transform.position = holderAttachPoint.TransformPoint(heldLocalOffset);
|
||||
transform.rotation = holderAttachPoint.rotation;
|
||||
transform.localScale = baseLocalScale;
|
||||
|
||||
if (fireScript != null) fireScript.BindProjectile(this);
|
||||
|
||||
StartCoroutine(IgnoreOwnerTemporarily(owner, ignoreOwnerTimeOnThrow));
|
||||
|
||||
CurrentState = State.Held;
|
||||
launched = false;
|
||||
hadBeenHeld = true;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private Transform ResolveAttachPoint(GameObject holder, Transform preferred = null)
|
||||
{
|
||||
if (preferred) return preferred;
|
||||
|
||||
var fs = holder.GetComponent<PlayerFireScript>();
|
||||
if (fs && fs.attachPoint) return fs.attachPoint;
|
||||
|
||||
return holder.transform;
|
||||
}
|
||||
|
||||
public void Launch(Vector2 direction, float speed, GameObject throwOwner = null)
|
||||
{
|
||||
if (CurrentState == State.Held)
|
||||
transform.SetParent(null, worldPositionStays: true);
|
||||
|
||||
owner = throwOwner;
|
||||
lastKnownHolder = throwOwner;
|
||||
holderAttachPoint = null;
|
||||
|
||||
rb.bodyType = RigidbodyType2D.Dynamic;
|
||||
col.enabled = true;
|
||||
|
||||
launched = true;
|
||||
|
||||
Vector2 dir = direction.sqrMagnitude > 0.0001f ? direction.normalized : Vector2.right;
|
||||
float finalSpeed = (speed > 0f) ? speed : initialSpeed;
|
||||
|
||||
rb.linearVelocity = Vector2.zero;
|
||||
rb.angularVelocity = 0f;
|
||||
rb.AddForce(dir * finalSpeed * rb.mass, ForceMode2D.Impulse);
|
||||
|
||||
transform.right = dir;
|
||||
transform.localScale = baseLocalScale;
|
||||
|
||||
if (throwOwner != null && ignoreOwnerTimeOnThrow > 0f)
|
||||
StartCoroutine(IgnoreOwnerTemporarily(throwOwner, ignoreOwnerTimeOnThrow));
|
||||
|
||||
CurrentState = State.Airborne;
|
||||
bounceCounter = 0;
|
||||
}
|
||||
|
||||
|
||||
protected override void OnImpactFinal(Collision2D collision)
|
||||
{
|
||||
if (!TryBounce(collision))
|
||||
@ -265,35 +263,16 @@ public class PickableProjectile : BasicProjectile
|
||||
bounceCounter = 0;
|
||||
}
|
||||
|
||||
private Transform FindAttachPointOn(GameObject who)
|
||||
private Transform FindAttachPoint(GameObject who)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(attachPointChildName)) return null;
|
||||
var t = who.transform.Find(attachPointChildName);
|
||||
return t;
|
||||
}
|
||||
|
||||
protected override void FixedUpdate()
|
||||
{
|
||||
base.FixedUpdate();
|
||||
|
||||
if (!lockWhenLanded && CurrentState == State.Airborne)
|
||||
{
|
||||
if (rb.linearVelocity.sqrMagnitude < (sleepVelocity * sleepVelocity))
|
||||
BecomeGrounded(null);
|
||||
}
|
||||
|
||||
// Бумеранг только если снаряд когда-то уже был в руке
|
||||
if (hadBeenHeld && CurrentState != State.Held)
|
||||
HandleRecallToPlayer();
|
||||
}
|
||||
|
||||
private void HandleRecallToPlayer()
|
||||
{
|
||||
// Целимся в актуального игрока, предпочтительно последнего владельца
|
||||
GameObject playerGo = null;
|
||||
|
||||
if (lastKnownHolder != null)
|
||||
playerGo = lastKnownHolder;
|
||||
GameObject playerGo = lastKnownHolder;
|
||||
|
||||
if (playerGo == null || !playerGo.activeInHierarchy)
|
||||
playerGo = (GameManager.Instance && GameManager.Instance.playerObj)
|
||||
@ -302,20 +281,18 @@ public class PickableProjectile : BasicProjectile
|
||||
|
||||
if (!playerGo) return;
|
||||
|
||||
var hand = FindAttachPointOn(playerGo) ?? playerGo.transform;
|
||||
var hand = ResolveAttachPoint(playerGo);
|
||||
|
||||
Vector2 toHand = (Vector2)hand.position - rb.position;
|
||||
float dist = toHand.magnitude;
|
||||
|
||||
if (dist > recallStartDistance)
|
||||
{
|
||||
// Начинаем «магнит»
|
||||
if (CurrentState != State.Returning)
|
||||
{
|
||||
CurrentState = State.Returning;
|
||||
rb.bodyType = RigidbodyType2D.Dynamic;
|
||||
col.enabled = true;
|
||||
// ВАЖНО: не игнорируем коллизию с игроком здесь, чтобы не проскальзывать через него
|
||||
}
|
||||
|
||||
Vector2 desired = toHand.normalized * recallMaxSpeed;
|
||||
@ -326,13 +303,11 @@ public class PickableProjectile : BasicProjectile
|
||||
transform.right = rb.linearVelocity.normalized;
|
||||
|
||||
if (dist <= recallArriveDistance)
|
||||
TryPickup(playerGo, hand);
|
||||
TryPickup(playerGo);
|
||||
}
|
||||
else
|
||||
else if (CurrentState == State.Returning)
|
||||
{
|
||||
// Вышли из «дальней» зоны — возвращаем обычное состояние
|
||||
if (CurrentState == State.Returning)
|
||||
CurrentState = rb.bodyType == RigidbodyType2D.Dynamic ? State.Airborne : State.Grounded;
|
||||
CurrentState = rb.bodyType == RigidbodyType2D.Dynamic ? State.Airborne : State.Grounded;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
319
Assets/Resources/Scripts/Temp.cs
Normal file
319
Assets/Resources/Scripts/Temp.cs
Normal file
@ -0,0 +1,319 @@
|
||||
using UnityEngine;
|
||||
|
||||
[DisallowMultipleComponent]
|
||||
[RequireComponent(typeof(Rigidbody2D))]
|
||||
[RequireComponent(typeof(Collider2D))]
|
||||
public class PickableProjectileTemp : BasicProjectile
|
||||
{
|
||||
// --- Singleton ---
|
||||
public static PickableProjectileTemp Instance { get; private set; }
|
||||
|
||||
public enum State { Held, Airborne, Grounded, Returning }
|
||||
public State CurrentState { get; private set; } = State.Grounded;
|
||||
|
||||
[Header("Pickup/Attach")]
|
||||
public Vector3 heldLocalOffset = new(0.25f, 0.1f, 0f);
|
||||
public float ignoreOwnerTimeOnThrow = 0.25f;
|
||||
public string attachPointChildName = "HandPoint";
|
||||
|
||||
[Header("Physics on ground")]
|
||||
public float sleepVelocity = 0.05f;
|
||||
public bool lockWhenLanded = true;
|
||||
|
||||
[Header("Bouncing")]
|
||||
public int maxBounces = 3;
|
||||
public float minBounceSpeed = 0.8f;
|
||||
[Range(0f, 1f)] public float restitution = 0.6f;
|
||||
[Range(0f, 1f)] public float tangentDamping = 0.85f;
|
||||
[Range(0f, 1f)] public float groundUpTolerance = 0.25f;
|
||||
public float stickDelayAfterImpact = 0.03f;
|
||||
|
||||
[Header("Recall")]
|
||||
public float recallStartDistance = 8f;
|
||||
public float recallArriveDistance = 1f;
|
||||
public float recallMaxSpeed = 16f;
|
||||
public float recallAcceleration = 60f;
|
||||
|
||||
[Header("Gizmos")]
|
||||
public bool drawGizmos;
|
||||
public Color gizmoColor = new Color(0.2f, 0.8f, 1f, 0.35f);
|
||||
|
||||
private Transform holderAttachPoint;
|
||||
private int bounceCounter = 0;
|
||||
private float lastImpactTime = -999f;
|
||||
|
||||
private bool hadBeenHeld = false;
|
||||
private GameObject lastKnownHolder;
|
||||
|
||||
// локальный «таймер» игнора владельца после броска,
|
||||
// чтобы не подбирать мгновенно владельцем при столкновении
|
||||
private float ignoreOwnerUntil = -999f;
|
||||
|
||||
protected override void Awake()
|
||||
{
|
||||
base.Awake();
|
||||
if (Instance != null && Instance != this)
|
||||
{
|
||||
Destroy(gameObject);
|
||||
return;
|
||||
}
|
||||
Instance = this;
|
||||
}
|
||||
|
||||
private void OnDestroy()
|
||||
{
|
||||
if (Instance == this) Instance = null;
|
||||
}
|
||||
|
||||
private void Start()
|
||||
{
|
||||
rb.collisionDetectionMode = CollisionDetectionMode2D.Continuous;
|
||||
col.isTrigger = false;
|
||||
|
||||
if (CurrentState != State.Held)
|
||||
BecomeGrounded(null);
|
||||
}
|
||||
|
||||
public bool TryPickup(GameObject newHolder, Transform optionalAttachPoint = null)
|
||||
{
|
||||
if (CurrentState == State.Held) return true;
|
||||
|
||||
owner = newHolder;
|
||||
lastKnownHolder = newHolder;
|
||||
|
||||
holderAttachPoint = optionalAttachPoint ?? FindAttachPointOn(owner);
|
||||
if (holderAttachPoint == null) holderAttachPoint = owner.transform;
|
||||
|
||||
rb.linearVelocity = Vector2.zero;
|
||||
rb.angularVelocity = 0f;
|
||||
rb.bodyType = RigidbodyType2D.Kinematic;
|
||||
col.enabled = false;
|
||||
|
||||
transform.SetParent(holderAttachPoint, worldPositionStays: false);
|
||||
transform.localPosition = heldLocalOffset;
|
||||
transform.localRotation = Quaternion.identity;
|
||||
transform.localScale = Vector3.one * 2;
|
||||
|
||||
// чуть-чуть игнорим владельца, чтобы не словить повторные коллизии
|
||||
ignoreOwnerUntil = Time.time + ignoreOwnerTimeOnThrow;
|
||||
|
||||
StartCoroutine(IgnoreOwnerTemporarily(owner, ignoreOwnerTimeOnThrow));
|
||||
|
||||
CurrentState = State.Held;
|
||||
launched = false;
|
||||
|
||||
hadBeenHeld = true;
|
||||
|
||||
// передадим ссылку игроку (если у него есть PlayerFireScript),
|
||||
// чтобы он знал «свой» снаряд
|
||||
var pfs = owner.GetComponent<PlayerFireScript>();
|
||||
//if (pfs) pfs.BindProjectile(this);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public void Launch(Vector2 direction, float speed, GameObject throwOwner = null)
|
||||
{
|
||||
if (CurrentState == State.Held)
|
||||
transform.SetParent(null, true);
|
||||
|
||||
owner = throwOwner;
|
||||
lastKnownHolder = throwOwner;
|
||||
holderAttachPoint = null;
|
||||
|
||||
rb.bodyType = RigidbodyType2D.Dynamic;
|
||||
col.enabled = true;
|
||||
|
||||
launched = true;
|
||||
|
||||
Vector2 dir = direction.sqrMagnitude > 0.0001f ? direction.normalized : Vector2.right;
|
||||
float finalSpeed = (speed > 0f) ? speed : initialSpeed;
|
||||
|
||||
rb.linearVelocity = Vector2.zero;
|
||||
rb.angularVelocity = 0f;
|
||||
rb.AddForce(dir * finalSpeed * rb.mass, ForceMode2D.Impulse);
|
||||
transform.right = dir;
|
||||
|
||||
if (throwOwner != null && ignoreOwnerTimeOnThrow > 0f)
|
||||
{
|
||||
ignoreOwnerUntil = Time.time + ignoreOwnerTimeOnThrow;
|
||||
StartCoroutine(IgnoreOwnerTemporarily(throwOwner, ignoreOwnerTimeOnThrow));
|
||||
}
|
||||
|
||||
CurrentState = State.Airborne;
|
||||
bounceCounter = 0;
|
||||
}
|
||||
|
||||
protected override void OnCollisionEnter2D(Collision2D collision)
|
||||
{
|
||||
// 1) если врезались в игрока — пробуем подобрать до логики рикошета
|
||||
var otherRb = collision.rigidbody ? collision.rigidbody : collision.otherRigidbody;
|
||||
var otherGo = (collision.collider ? collision.collider.attachedRigidbody?.gameObject : null)
|
||||
?? otherRb?.gameObject
|
||||
?? collision.gameObject;
|
||||
|
||||
if (otherGo && otherGo.CompareTag("Player") && CurrentState != State.Held)
|
||||
{
|
||||
// не подбираем мгновенно того же владельца, если ещё в «игноре»
|
||||
if (otherGo != owner || Time.time >= ignoreOwnerUntil)
|
||||
{
|
||||
var hand = FindAttachPointOn(otherGo) ?? otherGo.transform;
|
||||
if (TryPickup(otherGo, hand)) return; // успешно подобрали — выходим
|
||||
}
|
||||
}
|
||||
|
||||
// 2) обычная логика попадания/рикошета
|
||||
base.OnCollisionEnter2D(collision);
|
||||
|
||||
if (CurrentState == State.Airborne)
|
||||
{
|
||||
if (TryBounce(collision))
|
||||
{
|
||||
lastImpactTime = Time.time;
|
||||
return;
|
||||
}
|
||||
|
||||
BecomeGrounded(collision);
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnImpactFinal(Collision2D collision)
|
||||
{
|
||||
if (!TryBounce(collision))
|
||||
BecomeGrounded(collision);
|
||||
}
|
||||
|
||||
protected override void OnImpactFinal(Collider2D other)
|
||||
{
|
||||
if (Time.time - lastImpactTime > stickDelayAfterImpact)
|
||||
BecomeGrounded(null);
|
||||
}
|
||||
|
||||
private bool TryBounce(Collision2D collision)
|
||||
{
|
||||
if (Time.time - lastImpactTime < stickDelayAfterImpact)
|
||||
return true;
|
||||
|
||||
var v = rb.linearVelocity;
|
||||
float speed = v.magnitude;
|
||||
if (speed < minBounceSpeed) return false;
|
||||
|
||||
Vector2 avgNormal = Vector2.up;
|
||||
if (collision.contactCount > 0)
|
||||
{
|
||||
avgNormal = Vector2.zero;
|
||||
for (int i = 0; i < collision.contactCount; i++)
|
||||
avgNormal += collision.GetContact(i).normal;
|
||||
avgNormal.Normalize();
|
||||
}
|
||||
|
||||
Vector2 reflected = Vector2.Reflect(v, avgNormal) * restitution;
|
||||
|
||||
Vector2 n = avgNormal;
|
||||
Vector2 vn = Vector2.Dot(reflected, n) * n;
|
||||
Vector2 vt = reflected - vn;
|
||||
reflected = vn + vt * tangentDamping;
|
||||
|
||||
rb.linearVelocity = reflected;
|
||||
rb.position += n * 0.005f;
|
||||
|
||||
bounceCounter++;
|
||||
|
||||
if (bounceCounter >= maxBounces)
|
||||
return false;
|
||||
|
||||
CurrentState = State.Airborne;
|
||||
return true;
|
||||
}
|
||||
|
||||
private void BecomeGrounded(Collision2D collision)
|
||||
{
|
||||
launched = false;
|
||||
CurrentState = State.Grounded;
|
||||
|
||||
if (lockWhenLanded)
|
||||
{
|
||||
rb.linearVelocity = Vector2.zero;
|
||||
rb.angularVelocity = 0f;
|
||||
rb.bodyType = RigidbodyType2D.Kinematic;
|
||||
}
|
||||
else
|
||||
{
|
||||
rb.bodyType = RigidbodyType2D.Dynamic;
|
||||
}
|
||||
|
||||
col.enabled = true;
|
||||
transform.SetParent(null, true);
|
||||
bounceCounter = 0;
|
||||
}
|
||||
|
||||
private Transform FindAttachPointOn(GameObject who)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(attachPointChildName)) return null;
|
||||
return who.transform.Find(attachPointChildName);
|
||||
}
|
||||
|
||||
protected override void FixedUpdate()
|
||||
{
|
||||
base.FixedUpdate();
|
||||
|
||||
if (!lockWhenLanded && CurrentState == State.Airborne)
|
||||
{
|
||||
if (rb.linearVelocity.sqrMagnitude < (sleepVelocity * sleepVelocity))
|
||||
BecomeGrounded(null);
|
||||
}
|
||||
|
||||
if (hadBeenHeld && CurrentState != State.Held)
|
||||
HandleRecallToPlayer();
|
||||
}
|
||||
|
||||
private void HandleRecallToPlayer()
|
||||
{
|
||||
GameObject playerGo = lastKnownHolder;
|
||||
|
||||
if (playerGo == null || !playerGo.activeInHierarchy)
|
||||
playerGo = GameObject.FindWithTag("Player");
|
||||
|
||||
if (!playerGo) return;
|
||||
|
||||
var hand = FindAttachPointOn(playerGo) ?? playerGo.transform;
|
||||
|
||||
Vector2 toHand = (Vector2)hand.position - rb.position;
|
||||
float dist = toHand.magnitude;
|
||||
|
||||
if (dist > recallStartDistance)
|
||||
{
|
||||
if (CurrentState != State.Returning)
|
||||
{
|
||||
CurrentState = State.Returning;
|
||||
rb.bodyType = RigidbodyType2D.Dynamic;
|
||||
col.enabled = true;
|
||||
}
|
||||
|
||||
Vector2 desired = toHand.normalized * recallMaxSpeed;
|
||||
rb.linearVelocity = Vector2.MoveTowards(
|
||||
rb.linearVelocity, desired, recallAcceleration * Time.fixedDeltaTime);
|
||||
|
||||
if (rb.linearVelocity.sqrMagnitude > 0.01f)
|
||||
transform.right = rb.linearVelocity.normalized;
|
||||
|
||||
if (dist <= recallArriveDistance)
|
||||
TryPickup(playerGo, hand);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (CurrentState == State.Returning)
|
||||
CurrentState = rb.bodyType == RigidbodyType2D.Dynamic ? State.Airborne : State.Grounded;
|
||||
}
|
||||
}
|
||||
|
||||
#if UNITY_EDITOR
|
||||
private void OnDrawGizmosSelected()
|
||||
{
|
||||
if (!drawGizmos) return;
|
||||
Gizmos.color = gizmoColor;
|
||||
Gizmos.matrix = transform.localToWorldMatrix;
|
||||
Gizmos.DrawCube(new Vector3(heldLocalOffset.x, heldLocalOffset.y, 0), new Vector3(0.12f, 0.12f, 0.02f));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
2
Assets/Resources/Scripts/Temp.cs.meta
Normal file
2
Assets/Resources/Scripts/Temp.cs.meta
Normal file
@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: cfcb58e623aec0347a14faffcc5b438c
|
||||
@ -141,7 +141,8 @@ PlayerSettings:
|
||||
visionOSBundleVersion: 1.0
|
||||
tvOSBundleVersion: 1.0
|
||||
bundleVersion: 1.0
|
||||
preloadedAssets: []
|
||||
preloadedAssets:
|
||||
- {fileID: -944628639613478452, guid: 2bcd2660ca9b64942af0de543d8d7100, type: 3}
|
||||
metroInputSource: 0
|
||||
wsaTransparentSwapchain: 0
|
||||
m_HolographicPauseOnTrackingLoss: 1
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user