Added NavMesh link support.
This commit is contained in:
parent
ac200e9085
commit
6b0748c755
@ -6,6 +6,9 @@ using System.IO;
|
|||||||
using System.Text;
|
using System.Text;
|
||||||
using Unity.Mathematics;
|
using Unity.Mathematics;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using Unity.AI.Navigation;
|
||||||
|
using UnityEngine.AI;
|
||||||
|
|
||||||
namespace FrameJosh.SplineImporter
|
namespace FrameJosh.SplineImporter
|
||||||
{
|
{
|
||||||
@ -22,91 +25,97 @@ namespace FrameJosh.SplineImporter
|
|||||||
|
|
||||||
if (GUILayout.Button("Import Spline"))
|
if (GUILayout.Button("Import Spline"))
|
||||||
{
|
{
|
||||||
SplineImporter splineImporter = target as SplineImporter;
|
var splineImporter = (SplineImporter)target;
|
||||||
|
|
||||||
splineImporter.name = splineImporter.splineData.name;
|
splineImporter.name = splineImporter.splineData.name;
|
||||||
|
var splineData = JsonUtility.FromJson<SplineData>(splineImporter.splineData.text);
|
||||||
SplineData splineData = JsonUtility.FromJson<SplineData>(splineImporter.splineData.text);
|
var splineContainer = splineImporter.GetComponent<SplineContainer>();
|
||||||
|
foreach (var thisSpline in splineContainer.Splines) splineContainer.RemoveSpline(thisSpline);
|
||||||
SplineContainer splineContainer = splineImporter.GetComponent<SplineContainer>();
|
#if COM_UNITY_AI_NAVIGATION
|
||||||
|
Undo.IncrementCurrentGroup();
|
||||||
foreach (UnityEngine.Splines.Spline thisSpline in splineContainer.Splines)
|
var children = (from Transform child in splineImporter.transform select child.gameObject).ToList();
|
||||||
splineContainer.RemoveSpline(thisSpline);
|
children.ForEach(Undo.DestroyObjectImmediate);
|
||||||
|
#endif
|
||||||
foreach (SplineData.Spline thisDataSpline in splineData.splines)
|
foreach (var thisDataSpline in splineData.splines)
|
||||||
{
|
{
|
||||||
UnityEngine.Splines.Spline thisSpline = splineContainer.AddSpline();
|
var thisSpline = splineContainer.AddSpline();
|
||||||
|
|
||||||
thisSpline.Closed = thisDataSpline.closed;
|
thisSpline.Closed = thisDataSpline.closed;
|
||||||
|
foreach (var thisControlPoint in thisDataSpline.controlPoints)
|
||||||
foreach (ControlPoint thisControlPoint in thisDataSpline.controlPoints)
|
|
||||||
{
|
{
|
||||||
Vector3 position = PositionToVector(thisControlPoint.position);
|
var position = thisControlPoint.position;
|
||||||
|
var handleL = thisControlPoint.handleL;
|
||||||
|
var handleR = thisControlPoint.handleR;
|
||||||
|
var rotation = Quaternion.LookRotation((float3)handleR - position, Vector3.up) *
|
||||||
|
Quaternion.AngleAxis(-thisControlPoint.tilt, Vector3.forward);
|
||||||
|
|
||||||
Vector3 handleL = PositionToVector(thisControlPoint.handleL);
|
float3x3 rotationMatrix = new(rotation);
|
||||||
|
|
||||||
Vector3 handleR = PositionToVector(thisControlPoint.handleR);
|
thisSpline.Add(new BezierKnot
|
||||||
|
{
|
||||||
Quaternion rotation = Quaternion.LookRotation(handleR - position, Vector3.up) * Quaternion.AngleAxis(-thisControlPoint.tilt, Vector3.forward);
|
Position = position * splineImporter.scale,
|
||||||
|
Rotation = rotation,
|
||||||
float3x3 rotationMatrix = new float3x3(rotation);
|
TangentIn = math.mul((float3)handleL - position, rotationMatrix) * splineImporter.scale,
|
||||||
|
TangentOut = math.mul((float3)handleR - position, rotationMatrix) * splineImporter.scale
|
||||||
thisSpline.Add(new()
|
},
|
||||||
{
|
TangentMode.Broken);
|
||||||
Position = position * splineImporter.scale,
|
|
||||||
Rotation = rotation,
|
|
||||||
TangentIn = ((Vector3)math.mul(handleL - position, rotationMatrix)) * splineImporter.scale,
|
|
||||||
TangentOut = ((Vector3)math.mul(handleR - position, rotationMatrix)) * splineImporter.scale
|
|
||||||
},
|
|
||||||
TangentMode.Broken);
|
|
||||||
}
|
}
|
||||||
|
#if COM_UNITY_AI_NAVIGATION
|
||||||
|
if (thisDataSpline.closed) continue;
|
||||||
|
var go = new GameObject
|
||||||
|
{
|
||||||
|
transform =
|
||||||
|
{
|
||||||
|
parent = splineImporter.transform
|
||||||
|
}
|
||||||
|
};
|
||||||
|
var link = go.AddComponent<NavMeshLink>();
|
||||||
|
var startPoint = thisDataSpline.controlPoints[0].position * splineImporter.scale;
|
||||||
|
if (NavMesh.SamplePosition(startPoint, out var startHit, 2f, NavMesh.AllAreas))
|
||||||
|
startPoint = startHit.position;
|
||||||
|
var endPoint = thisDataSpline.controlPoints[^1].position * splineImporter.scale;
|
||||||
|
if (NavMesh.SamplePosition(endPoint, out var endHit, 2f, NavMesh.AllAreas))
|
||||||
|
endPoint = endHit.position;
|
||||||
|
link.startPoint = startPoint;
|
||||||
|
link.endPoint = endPoint;
|
||||||
|
Undo.RegisterCreatedObjectUndo(go, $"Create link from {startPoint} to {endPoint}");
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (GUILayout.Button("Export Spline"))
|
if (GUILayout.Button("Export Spline"))
|
||||||
{
|
{
|
||||||
SplineImporter splineImporter = target as SplineImporter;
|
var splineImporter = (SplineImporter)target;
|
||||||
|
|
||||||
if (!splineImporter.splineData)
|
if (!splineImporter.splineData)
|
||||||
{
|
{
|
||||||
string path = "Assets" + EditorUtility.SaveFilePanel("Save .JSON", "", "New Spline.json", "json").Substring(Application.dataPath.Length);
|
var path = "Assets" +
|
||||||
|
EditorUtility.SaveFilePanel("Save .JSON", "", "New Spline.json", "json")[
|
||||||
|
Application.dataPath.Length..];
|
||||||
if (path.Length > 0)
|
if (path.Length > 0)
|
||||||
{
|
{
|
||||||
File.WriteAllBytes(path, Encoding.ASCII.GetBytes(""));
|
File.WriteAllBytes(path, Encoding.ASCII.GetBytes(""));
|
||||||
|
|
||||||
AssetDatabase.Refresh();
|
AssetDatabase.Refresh();
|
||||||
|
var textAsset = AssetDatabase.LoadAssetAtPath(path, typeof(TextAsset)) as TextAsset;
|
||||||
TextAsset textAsset = AssetDatabase.LoadAssetAtPath(path, typeof(TextAsset)) as TextAsset;
|
|
||||||
|
|
||||||
splineImporter.splineData = textAsset;
|
splineImporter.splineData = textAsset;
|
||||||
}
|
}
|
||||||
else return;
|
else return;
|
||||||
}
|
}
|
||||||
|
|
||||||
SplineContainer splineContainer = splineImporter.GetComponent<SplineContainer>();
|
var splineContainer = splineImporter.GetComponent<SplineContainer>();
|
||||||
|
SplineData splineData = new()
|
||||||
SplineData splineData = new();
|
{
|
||||||
|
splines = new Spline[splineContainer.Splines.Count]
|
||||||
splineData.splines = new SplineData.Spline[splineContainer.Splines.Count];
|
};
|
||||||
|
List<Spline> dataSplines = new();
|
||||||
List<SplineData.Spline> dataSplines = new();
|
foreach (var thisSpline in splineContainer.Splines)
|
||||||
|
|
||||||
foreach (UnityEngine.Splines.Spline thisSpline in splineContainer.Splines)
|
|
||||||
{
|
{
|
||||||
List<ControlPoint> controlPoints = new();
|
List<ControlPoint> controlPoints = new();
|
||||||
|
foreach (var thisBezierKnot in thisSpline.Knots)
|
||||||
foreach (BezierKnot thisBezierKnot in thisSpline.Knots)
|
|
||||||
{
|
{
|
||||||
Position position = VectorToPosition(thisBezierKnot.Position);
|
Position position = thisBezierKnot.Position;
|
||||||
|
float3x3 rotationMatrix = new(Quaternion.Inverse(thisBezierKnot.Rotation));
|
||||||
float3x3 rotationMatrix = new float3x3(Quaternion.Inverse(thisBezierKnot.Rotation));
|
Position handleL = math.mul(thisBezierKnot.TangentIn, rotationMatrix) + thisBezierKnot.Position;
|
||||||
|
Position handleR = math.mul(thisBezierKnot.TangentOut, rotationMatrix) +
|
||||||
Position handleL = VectorToPosition(math.mul(thisBezierKnot.TangentIn, rotationMatrix) + thisBezierKnot.Position);
|
thisBezierKnot.Position;
|
||||||
|
controlPoints.Add(new ControlPoint
|
||||||
Position handleR = VectorToPosition(math.mul(thisBezierKnot.TangentOut, rotationMatrix) + thisBezierKnot.Position);
|
|
||||||
|
|
||||||
controlPoints.Add(new()
|
|
||||||
{
|
{
|
||||||
position = position,
|
position = position,
|
||||||
handleL = handleL,
|
handleL = handleL,
|
||||||
@ -114,7 +123,7 @@ namespace FrameJosh.SplineImporter
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
dataSplines.Add(new()
|
dataSplines.Add(new Spline
|
||||||
{
|
{
|
||||||
controlPoints = controlPoints.ToArray(),
|
controlPoints = controlPoints.ToArray(),
|
||||||
closed = thisSpline.Closed
|
closed = thisSpline.Closed
|
||||||
@ -123,12 +132,14 @@ namespace FrameJosh.SplineImporter
|
|||||||
|
|
||||||
splineData.splines = dataSplines.ToArray();
|
splineData.splines = dataSplines.ToArray();
|
||||||
|
|
||||||
File.WriteAllText(AssetDatabase.GetAssetPath(splineImporter.splineData), JsonUtility.ToJson(splineData, true));
|
File.WriteAllText(AssetDatabase.GetAssetPath(splineImporter.splineData),
|
||||||
|
JsonUtility.ToJson(splineData, true));
|
||||||
|
|
||||||
AssetDatabase.Refresh();
|
AssetDatabase.Refresh();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[RequireComponent(typeof(SplineContainer))]
|
[RequireComponent(typeof(SplineContainer))]
|
||||||
#endif
|
#endif
|
||||||
public class SplineImporter : MonoBehaviour
|
public class SplineImporter : MonoBehaviour
|
||||||
@ -136,22 +147,7 @@ namespace FrameJosh.SplineImporter
|
|||||||
#if UNITY_EDITOR
|
#if UNITY_EDITOR
|
||||||
public TextAsset splineData;
|
public TextAsset splineData;
|
||||||
|
|
||||||
public float3 scale = new (1f, 1f, 1f);
|
public float3 scale = new(1f, 1f, 1f);
|
||||||
|
|
||||||
public static Vector3 PositionToVector(Position position)
|
|
||||||
{
|
|
||||||
return new(position.x, position.z, position.y);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Position VectorToPosition(Vector3 vector)
|
|
||||||
{
|
|
||||||
return new()
|
|
||||||
{
|
|
||||||
x = vector.x,
|
|
||||||
y = vector.z,
|
|
||||||
z = vector.y
|
|
||||||
};
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
#if UNITY_EDITOR
|
#if UNITY_EDITOR
|
||||||
@ -162,21 +158,31 @@ namespace FrameJosh.SplineImporter
|
|||||||
public struct Position
|
public struct Position
|
||||||
{
|
{
|
||||||
public float x;
|
public float x;
|
||||||
|
|
||||||
public float y;
|
public float y;
|
||||||
|
|
||||||
public float z;
|
public float z;
|
||||||
|
|
||||||
|
public static implicit operator Position(float3 vector)
|
||||||
|
{
|
||||||
|
return new Position
|
||||||
|
{
|
||||||
|
x = vector.x,
|
||||||
|
y = vector.z,
|
||||||
|
z = vector.y
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public static implicit operator float3(Position vector)
|
||||||
|
{
|
||||||
|
return new float3(vector.x, vector.z, vector.y);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[Serializable]
|
[Serializable]
|
||||||
public struct ControlPoint
|
public struct ControlPoint
|
||||||
{
|
{
|
||||||
public Position position;
|
public Position position;
|
||||||
|
|
||||||
public Position handleL;
|
public Position handleL;
|
||||||
|
|
||||||
public Position handleR;
|
public Position handleR;
|
||||||
|
|
||||||
public float tilt;
|
public float tilt;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -188,7 +194,7 @@ namespace FrameJosh.SplineImporter
|
|||||||
public bool closed;
|
public bool closed;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Spline[] splines = new Spline[0];
|
public Spline[] splines = Array.Empty<Spline>();
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
@ -3,7 +3,8 @@
|
|||||||
"rootNamespace": "",
|
"rootNamespace": "",
|
||||||
"references": [
|
"references": [
|
||||||
"Unity.Splines",
|
"Unity.Splines",
|
||||||
"Unity.Mathematics"
|
"Unity.Mathematics",
|
||||||
|
"Unity.AI.Navigation"
|
||||||
],
|
],
|
||||||
"includePlatforms": [],
|
"includePlatforms": [],
|
||||||
"excludePlatforms": [],
|
"excludePlatforms": [],
|
||||||
@ -12,6 +13,12 @@
|
|||||||
"precompiledReferences": [],
|
"precompiledReferences": [],
|
||||||
"autoReferenced": true,
|
"autoReferenced": true,
|
||||||
"defineConstraints": [],
|
"defineConstraints": [],
|
||||||
"versionDefines": [],
|
"versionDefines": [
|
||||||
|
{
|
||||||
|
"name": "com.unity.ai.navigation",
|
||||||
|
"expression": "",
|
||||||
|
"define": "COM_UNITY_AI_NAVIGATION"
|
||||||
|
}
|
||||||
|
],
|
||||||
"noEngineReferences": false
|
"noEngineReferences": false
|
||||||
}
|
}
|
@ -1,13 +1,14 @@
|
|||||||
{
|
{
|
||||||
"name": "ru.shazbot.spline-importer",
|
"name": "ru.shazbot.spline-importer",
|
||||||
"version": "2.0.2",
|
"version": "3.0.0",
|
||||||
"displayName": "Spline Importer",
|
"displayName": "Spline Importer",
|
||||||
"description": "Import and export splines between Blender and Unity.",
|
"description": "Import and export splines between Blender and Unity.",
|
||||||
"unity": "2021.3",
|
"unity": "2021.3",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"com.unity.modules.jsonserialize": "1.0.0",
|
||||||
"com.unity.mathematics": "1.2.6",
|
"com.unity.mathematics": "1.2.6",
|
||||||
"com.unity.splines": "2.5.1"
|
"com.unity.splines": "2.5.1"
|
||||||
},
|
},
|
||||||
"author": {
|
"author": {
|
||||||
"name": "Alexander Filippov",
|
"name": "Alexander Filippov",
|
||||||
"email": "alexander@shazbot.ru",
|
"email": "alexander@shazbot.ru",
|
||||||
|
Loading…
x
Reference in New Issue
Block a user