Skip to content

Commit 669b1ad

Browse files
committed
feat: fish spline
1 parent 1ec50f5 commit 669b1ad

File tree

4 files changed

+294
-40
lines changed

4 files changed

+294
-40
lines changed

Assets/Scenes/Reparation.unity

+229-5
Original file line numberDiff line numberDiff line change
@@ -9207,11 +9207,10 @@ MonoBehaviour:
92079207
m_Script: {fileID: 11500000, guid: 77df7a834c991ce4c966b3383d967636, type: 3}
92089208
m_Name:
92099209
m_EditorClassIdentifier:
9210-
swimSpeed: 15
9211-
changeDirectionInterval: 10
9212-
swimHeight: 0.5
9213-
swimFrequency: 20
9214-
randomWanderAmount: 0.5
9210+
splineObject: {fileID: 557190188}
9211+
swimSpeed: 3
9212+
rotationSpeed: 5
9213+
loop: 1
92159214
--- !u!4 &509367958 stripped
92169215
Transform:
92179216
m_CorrespondingSourceObject: {fileID: 5146681718063874739, guid: 0cd2fb479650c304eac7efd1ad26408e, type: 3}
@@ -10550,6 +10549,198 @@ CanvasRenderer:
1055010549
m_PrefabAsset: {fileID: 0}
1055110550
m_GameObject: {fileID: 550523076}
1055210551
m_CullTransparentMesh: 1
10552+
--- !u!1 &557190188
10553+
GameObject:
10554+
m_ObjectHideFlags: 0
10555+
m_CorrespondingSourceObject: {fileID: 0}
10556+
m_PrefabInstance: {fileID: 0}
10557+
m_PrefabAsset: {fileID: 0}
10558+
serializedVersion: 6
10559+
m_Component:
10560+
- component: {fileID: 557190189}
10561+
- component: {fileID: 557190190}
10562+
m_Layer: 0
10563+
m_Name: Spline 1
10564+
m_TagString: Untagged
10565+
m_Icon: {fileID: 0}
10566+
m_NavMeshLayer: 0
10567+
m_StaticEditorFlags: 0
10568+
m_IsActive: 1
10569+
--- !u!4 &557190189
10570+
Transform:
10571+
m_ObjectHideFlags: 0
10572+
m_CorrespondingSourceObject: {fileID: 0}
10573+
m_PrefabInstance: {fileID: 0}
10574+
m_PrefabAsset: {fileID: 0}
10575+
m_GameObject: {fileID: 557190188}
10576+
serializedVersion: 2
10577+
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
10578+
m_LocalPosition: {x: 0, y: 0, z: 0}
10579+
m_LocalScale: {x: 1, y: 1, z: 1}
10580+
m_ConstrainProportionsScale: 0
10581+
m_Children: []
10582+
m_Father: {fileID: 1495273419}
10583+
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
10584+
--- !u!114 &557190190
10585+
MonoBehaviour:
10586+
m_ObjectHideFlags: 0
10587+
m_CorrespondingSourceObject: {fileID: 0}
10588+
m_PrefabInstance: {fileID: 0}
10589+
m_PrefabAsset: {fileID: 0}
10590+
m_GameObject: {fileID: 557190188}
10591+
m_Enabled: 1
10592+
m_EditorHideFlags: 0
10593+
m_Script: {fileID: 11500000, guid: dab5c7d4c32e743048dfca98e2d5914f, type: 3}
10594+
m_Name:
10595+
m_EditorClassIdentifier:
10596+
m_Spline:
10597+
m_EditModeType: 1
10598+
m_Knots: []
10599+
m_MetaData: []
10600+
m_Closed: 0
10601+
m_IntData:
10602+
m_Data: []
10603+
m_FloatData:
10604+
m_Data: []
10605+
m_Float4Data:
10606+
m_Data: []
10607+
m_ObjectData:
10608+
m_Data: []
10609+
m_Splines:
10610+
- m_EditModeType: 1
10611+
m_Knots:
10612+
- Position:
10613+
x: 4.6
10614+
y: -15
10615+
z: -64.5
10616+
TangentIn:
10617+
x: 0
10618+
y: 0
10619+
z: -1
10620+
TangentOut:
10621+
x: 0
10622+
y: 0
10623+
z: 1
10624+
Rotation:
10625+
value:
10626+
x: 0
10627+
y: 0
10628+
z: 0
10629+
w: 1
10630+
- Position:
10631+
x: 30
10632+
y: -10
10633+
z: -74.8
10634+
TangentIn:
10635+
x: 0
10636+
y: 0
10637+
z: -1
10638+
TangentOut:
10639+
x: 0
10640+
y: 0
10641+
z: 1
10642+
Rotation:
10643+
value:
10644+
x: 0
10645+
y: 0
10646+
z: 0
10647+
w: 1
10648+
- Position:
10649+
x: 47.62
10650+
y: -20
10651+
z: -13.3
10652+
TangentIn:
10653+
x: 0
10654+
y: 0
10655+
z: -1
10656+
TangentOut:
10657+
x: 0
10658+
y: 0
10659+
z: 1
10660+
Rotation:
10661+
value:
10662+
x: 0
10663+
y: 0
10664+
z: 0
10665+
w: 1
10666+
- Position:
10667+
x: 23.9
10668+
y: -30
10669+
z: -8.26
10670+
TangentIn:
10671+
x: 0
10672+
y: 0
10673+
z: -1
10674+
TangentOut:
10675+
x: 0
10676+
y: 0
10677+
z: 1
10678+
Rotation:
10679+
value:
10680+
x: 0
10681+
y: 0
10682+
z: 0
10683+
w: 1
10684+
- Position:
10685+
x: 8.9
10686+
y: -14.97
10687+
z: -6.5
10688+
TangentIn:
10689+
x: 0
10690+
y: 0
10691+
z: -1
10692+
TangentOut:
10693+
x: 0
10694+
y: 0
10695+
z: 1
10696+
Rotation:
10697+
value:
10698+
x: 0
10699+
y: 0
10700+
z: 0
10701+
w: 1
10702+
- Position:
10703+
x: -5.6
10704+
y: -17
10705+
z: 12
10706+
TangentIn:
10707+
x: 0
10708+
y: 0
10709+
z: -1
10710+
TangentOut:
10711+
x: 0
10712+
y: 0
10713+
z: 1
10714+
Rotation:
10715+
value:
10716+
x: 0
10717+
y: 0
10718+
z: 0
10719+
w: 1
10720+
m_MetaData:
10721+
- Mode: 2
10722+
Tension: 0.5
10723+
- Mode: 2
10724+
Tension: 0.5
10725+
- Mode: 2
10726+
Tension: 0.5
10727+
- Mode: 2
10728+
Tension: 0.5
10729+
- Mode: 2
10730+
Tension: 0.5
10731+
- Mode: 2
10732+
Tension: 0.5
10733+
m_Closed: 1
10734+
m_IntData:
10735+
m_Data: []
10736+
m_FloatData:
10737+
m_Data: []
10738+
m_Float4Data:
10739+
m_Data: []
10740+
m_ObjectData:
10741+
m_Data: []
10742+
m_Knots:
10743+
m_KnotsLink: []
1055310744
--- !u!4 &557404567 stripped
1055410745
Transform:
1055510746
m_CorrespondingSourceObject: {fileID: -5819118886272102141, guid: 0dc7ed63429e1b045bdec55b2f62133f, type: 3}
@@ -30841,6 +31032,38 @@ Transform:
3084131032
m_CorrespondingSourceObject: {fileID: -5819118886272102141, guid: 445f30229dfa5814182e1cf3f70a53aa, type: 3}
3084231033
m_PrefabInstance: {fileID: 1935490292}
3084331034
m_PrefabAsset: {fileID: 0}
31035+
--- !u!1 &1495273417
31036+
GameObject:
31037+
m_ObjectHideFlags: 0
31038+
m_CorrespondingSourceObject: {fileID: 0}
31039+
m_PrefabInstance: {fileID: 0}
31040+
m_PrefabAsset: {fileID: 0}
31041+
serializedVersion: 6
31042+
m_Component:
31043+
- component: {fileID: 1495273419}
31044+
m_Layer: 0
31045+
m_Name: ----------- Fish Splines ----------------------------------
31046+
m_TagString: Untagged
31047+
m_Icon: {fileID: 0}
31048+
m_NavMeshLayer: 0
31049+
m_StaticEditorFlags: 0
31050+
m_IsActive: 1
31051+
--- !u!4 &1495273419
31052+
Transform:
31053+
m_ObjectHideFlags: 0
31054+
m_CorrespondingSourceObject: {fileID: 0}
31055+
m_PrefabInstance: {fileID: 0}
31056+
m_PrefabAsset: {fileID: 0}
31057+
m_GameObject: {fileID: 1495273417}
31058+
serializedVersion: 2
31059+
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
31060+
m_LocalPosition: {x: -15.590047, y: 5.8634176, z: 9.638606}
31061+
m_LocalScale: {x: 1, y: 1, z: 1}
31062+
m_ConstrainProportionsScale: 0
31063+
m_Children:
31064+
- {fileID: 557190189}
31065+
m_Father: {fileID: 0}
31066+
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
3084431067
--- !u!1 &1497520578
3084531068
GameObject:
3084631069
m_ObjectHideFlags: 0
@@ -44522,3 +44745,4 @@ SceneRoots:
4452244745
- {fileID: 1743274444}
4452344746
- {fileID: 2129618630}
4452444747
- {fileID: 2033713812}
44748+
- {fileID: 1495273419}

Assets/Scripts/Creatures/Fish.cs

+53-35
Original file line numberDiff line numberDiff line change
@@ -1,61 +1,79 @@
11
using System.Collections;
22
using System.Collections.Generic;
33
using UnityEngine;
4+
using UnityEngine.Splines;
45

56
public class Fish : MonoBehaviour
67
{
7-
public float swimSpeed = 2f;
8-
public float changeDirectionInterval = 2f;
9-
public float swimHeight = 0.5f;
10-
public float swimFrequency = 1f;
11-
public float randomWanderAmount = 0.5f;
8+
public GameObject splineObject; // Reference to the GameObject that holds the SplineContainer
9+
public float swimSpeed = 1f; // Speed along the spline
10+
public float rotationSpeed = 2f; // Speed of rotation to face the spline direction
11+
public bool loop = true; // Should the fish loop back to the start of the spline?
1212

13-
private Vector2 _direction;
14-
private float _timer;
15-
private float _initialY;
13+
private float _progress; // Progress along the spline (0 to 1)
14+
private SplineContainer _splineContainer;
15+
private Spline _spline;
16+
private Vector3 _previousPosition;
1617

1718
private void Start()
1819
{
19-
ChangeDirection();
20-
_timer = changeDirectionInterval;
21-
_initialY = transform.position.y;
20+
// Check if splineObject is assigned, then get the SplineContainer component
21+
if (splineObject != null)
22+
{
23+
_splineContainer = splineObject.GetComponent<SplineContainer>();
24+
if (_splineContainer == null)
25+
{
26+
Debug.LogError("No SplineContainer found on the referenced GameObject.");
27+
return;
28+
}
29+
}
30+
else
31+
{
32+
Debug.LogError("No GameObject with a SplineContainer assigned to Fish.");
33+
return;
34+
}
35+
36+
// Get the spline from the container
37+
_spline = _splineContainer.Spline;
38+
_previousPosition = transform.position;
2239
}
2340

2441
private void Update()
2542
{
26-
transform.Translate(_direction * (swimSpeed * Time.deltaTime));
27-
float newY = _initialY + Mathf.Sin(Time.time * swimFrequency) * swimHeight;
28-
transform.position = new Vector3(transform.position.x, newY, transform.position.z);
43+
if (_spline == null) return;
44+
45+
// Move fish along the spline
46+
_progress += swimSpeed * Time.deltaTime / _spline.GetLength(); // Normalize speed across spline length
2947

30-
_timer -= Time.deltaTime;
31-
if (_timer <= 0f)
48+
if (_progress > 1f)
3249
{
33-
ChangeDirection();
34-
_timer = changeDirectionInterval;
50+
_progress = loop ? 0f : 1f; // Loop or clamp progress
3551
}
3652

37-
_direction += new Vector2(Random.Range(-randomWanderAmount, randomWanderAmount), Random.Range(-randomWanderAmount, randomWanderAmount));
38-
_direction.Normalize();
53+
// Get the position and tangent from the spline
54+
Vector3 currentPosition = _spline.EvaluatePosition(_progress);
55+
Vector3 tangent = _spline.EvaluateTangent(_progress);
3956

40-
Vector2 position = transform.position;
41-
if (position.x < -5 || position.x > 5 || position.y < -5 || position.y > 5)
42-
{
43-
_direction = -_direction;
44-
}
45-
}
57+
// Move the fish to the new position along the spline
58+
transform.position = currentPosition;
4659

47-
private void ChangeDirection()
48-
{
49-
float angle = Random.Range(0f, 360f);
50-
_direction = new Vector2(Mathf.Cos(angle), Mathf.Sin(angle)).normalized;
60+
// Rotate the fish to face the direction of movement (using tangent)
61+
Quaternion targetRotation = Quaternion.LookRotation(tangent);
62+
transform.rotation = Quaternion.Slerp(transform.rotation, targetRotation, rotationSpeed * Time.deltaTime);
63+
64+
_previousPosition = currentPosition;
5165
}
5266

53-
private void OnTriggerEnter2D(Collider2D other)
67+
private void OnDrawGizmos()
5468
{
55-
if (other.CompareTag("Player"))
69+
// Draw the spline path in the editor (optional)
70+
if (_splineContainer == null || _splineContainer.Spline == null) return;
71+
Gizmos.color = Color.cyan;
72+
Spline spline = _splineContainer.Spline;
73+
for (float t = 0; t < 1; t += 0.01f)
5674
{
57-
Vector2 fleeDirection = (transform.position - other.transform.position).normalized;
58-
_direction = fleeDirection;
75+
Vector3 point = spline.EvaluatePosition(t);
76+
Gizmos.DrawSphere(point, 0.05f);
5977
}
6078
}
61-
}
79+
}

Packages/manifest.json

+1
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
"com.unity.searcher": "4.9.2",
1919
"com.unity.settings-manager": "2.0.1",
2020
"com.unity.shadergraph": "14.0.11",
21+
"com.unity.splines": "2.6.1",
2122
"com.unity.test-framework": "1.1.33",
2223
"com.unity.testtools.codecoverage": "1.2.5",
2324
"com.unity.textmeshpro": "3.0.6",

0 commit comments

Comments
 (0)