mirror of
https://github.com/GTA-ASM/SanAndreasUnity
synced 2024-11-22 12:03:04 +00:00
create collision parts for water
This commit is contained in:
parent
30b9d56e36
commit
6185f7089f
4 changed files with 163 additions and 19 deletions
47
Assets/Prefabs/WaterCollision.prefab
Normal file
47
Assets/Prefabs/WaterCollision.prefab
Normal file
|
@ -0,0 +1,47 @@
|
|||
%YAML 1.1
|
||||
%TAG !u! tag:unity3d.com,2011:
|
||||
--- !u!1 &1851338461656571883
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
serializedVersion: 6
|
||||
m_Component:
|
||||
- component: {fileID: 7995634715881356742}
|
||||
- component: {fileID: 8546980230320474744}
|
||||
m_Layer: 4
|
||||
m_Name: WaterCollision
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!4 &7995634715881356742
|
||||
Transform:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 1851338461656571883}
|
||||
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_Children: []
|
||||
m_Father: {fileID: 0}
|
||||
m_RootOrder: 0
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
--- !u!64 &8546980230320474744
|
||||
MeshCollider:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 1851338461656571883}
|
||||
m_Material: {fileID: 0}
|
||||
m_IsTrigger: 1
|
||||
m_Enabled: 1
|
||||
serializedVersion: 4
|
||||
m_Convex: 1
|
||||
m_CookingOptions: 30
|
||||
m_Mesh: {fileID: 0}
|
7
Assets/Prefabs/WaterCollision.prefab.meta
Normal file
7
Assets/Prefabs/WaterCollision.prefab.meta
Normal file
|
@ -0,0 +1,7 @@
|
|||
fileFormatVersion: 2
|
||||
guid: e6c6e08b2f4ea5146acb88b9f1fd1529
|
||||
PrefabImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -691,6 +691,11 @@ MonoBehaviour:
|
|||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
WaterPrefab: {fileID: 100000, guid: 780611a67e8e941a2b3aa96e5915a793, type: 3}
|
||||
m_waterCollisionPrefab: {fileID: 1851338461656571883, guid: e6c6e08b2f4ea5146acb88b9f1fd1529,
|
||||
type: 3}
|
||||
m_createCollisionObjects: 1
|
||||
m_renderingObjects: []
|
||||
m_collisionObjects: []
|
||||
--- !u!1 &1000405462072482
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
using SanAndreasUnity.Importing.Items;
|
||||
using SanAndreasUnity.Importing.Items.Placements;
|
||||
using SanAndreasUnity.Utilities;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using UnityEngine;
|
||||
|
||||
|
@ -9,6 +10,12 @@ namespace SanAndreasUnity.Behaviours.World
|
|||
public class Water : MonoBehaviour
|
||||
{
|
||||
public GameObject WaterPrefab;
|
||||
[SerializeField] private GameObject m_waterCollisionPrefab;
|
||||
|
||||
[SerializeField] private bool m_createCollisionObjects = false;
|
||||
|
||||
[HideInInspector] [SerializeField] private List<Transform> m_renderingObjects = new List<Transform>();
|
||||
[HideInInspector] [SerializeField] private List<Transform> m_collisionObjects = new List<Transform>();
|
||||
|
||||
|
||||
public void Initialize(WaterFile file, Vector2 worldSize)
|
||||
|
@ -43,22 +50,7 @@ namespace SanAndreasUnity.Behaviours.World
|
|||
|
||||
foreach (var face in faces)
|
||||
{
|
||||
for (int j = 0; j < face.Vertices.Length; j++)
|
||||
{
|
||||
vertices[verticesIndex + j] = face.Vertices[j].Position;
|
||||
normals[verticesIndex + j] = Vector3.up;
|
||||
}
|
||||
|
||||
for (var j = 0; j < face.Vertices.Length - 2; ++j)
|
||||
{
|
||||
var flip = j & 1;
|
||||
indices[indicesIndex + j * 3 + 0] = verticesIndex + j + 1 - flip;
|
||||
indices[indicesIndex + j * 3 + 1] = verticesIndex + j + 0 + flip;
|
||||
indices[indicesIndex + j * 3 + 2] = verticesIndex + j + 2;
|
||||
}
|
||||
|
||||
verticesIndex += face.Vertices.Length;
|
||||
indicesIndex += (face.Vertices.Length - 2) * 3;
|
||||
ProcessFace(face, vertices, normals, ref verticesIndex, indices, ref indicesIndex);
|
||||
}
|
||||
|
||||
// add "infinite" water
|
||||
|
@ -107,7 +99,9 @@ namespace SanAndreasUnity.Behaviours.World
|
|||
mesh.normals = normals;
|
||||
mesh.SetIndices(indices, MeshTopology.Triangles, 0);
|
||||
|
||||
var availableObjects = this.transform.GetFirstLevelChildren().ToQueueWithCapacity(this.transform.childCount);
|
||||
m_renderingObjects.RemoveDeadObjects();
|
||||
|
||||
var availableObjects = m_renderingObjects.ToQueueWithCapacity(m_renderingObjects.Count);
|
||||
|
||||
var go = availableObjects.Count > 0
|
||||
? availableObjects.Dequeue().gameObject
|
||||
|
@ -116,7 +110,7 @@ namespace SanAndreasUnity.Behaviours.World
|
|||
go.transform.localPosition = Vector3.zero;
|
||||
go.transform.localRotation = Quaternion.identity;
|
||||
|
||||
go.name = "Water mesh";
|
||||
go.name = "Water rendering mesh";
|
||||
mesh.name = go.name;
|
||||
|
||||
var meshFilter = go.GetComponentOrThrow<MeshFilter>();
|
||||
|
@ -126,7 +120,98 @@ namespace SanAndreasUnity.Behaviours.World
|
|||
|
||||
foreach (var availableObject in availableObjects)
|
||||
F.DestroyEvenInEditMode(availableObject.gameObject);
|
||||
|
||||
|
||||
m_renderingObjects.Clear();
|
||||
m_renderingObjects.Add(go.transform);
|
||||
|
||||
|
||||
if (m_createCollisionObjects)
|
||||
CreateCollisionObjects(faces);
|
||||
|
||||
}
|
||||
|
||||
void ProcessFace(WaterFace face, Vector3[] vertices, Vector3[] normals, ref int verticesIndex, int[] indices, ref int indicesIndex)
|
||||
{
|
||||
for (int j = 0; j < face.Vertices.Length; j++)
|
||||
{
|
||||
vertices[verticesIndex + j] = face.Vertices[j].Position;
|
||||
normals[verticesIndex + j] = Vector3.up;
|
||||
}
|
||||
|
||||
for (var j = 0; j < face.Vertices.Length - 2; ++j)
|
||||
{
|
||||
var flip = j & 1;
|
||||
indices[indicesIndex + j * 3 + 0] = verticesIndex + j + 1 - flip;
|
||||
indices[indicesIndex + j * 3 + 1] = verticesIndex + j + 0 + flip;
|
||||
indices[indicesIndex + j * 3 + 2] = verticesIndex + j + 2;
|
||||
}
|
||||
|
||||
verticesIndex += face.Vertices.Length;
|
||||
indicesIndex += (face.Vertices.Length - 2) * 3;
|
||||
}
|
||||
|
||||
void CreateCollisionObjects(IEnumerable<WaterFace> faces)
|
||||
{
|
||||
if (null == m_waterCollisionPrefab)
|
||||
{
|
||||
Debug.LogError("Water collision prefab not set");
|
||||
return;
|
||||
}
|
||||
|
||||
m_collisionObjects.RemoveDeadObjects();
|
||||
|
||||
var availableObjects = m_collisionObjects.ToQueueWithCapacity(m_collisionObjects.Count);
|
||||
|
||||
m_collisionObjects.Clear();
|
||||
|
||||
int i = 0;
|
||||
foreach (var face in faces)
|
||||
{
|
||||
Vector3[] vertices = new Vector3[face.Vertices.Length];
|
||||
Vector3[] normals = new Vector3[face.Vertices.Length];
|
||||
int numIndices = (face.Vertices.Length - 2) * 3;
|
||||
int[] indices = new int[numIndices];
|
||||
|
||||
int verticesIndex = 0;
|
||||
int indicesIndex = 0;
|
||||
|
||||
ProcessFace(face, vertices, normals, ref verticesIndex, indices, ref indicesIndex);
|
||||
|
||||
Vector3 center = Vector3.zero;
|
||||
vertices.ForEach(v => center += v / vertices.Length);
|
||||
for (int v = 0; v < vertices.Length; v++)
|
||||
vertices[v] = vertices[v] - center;
|
||||
|
||||
var mesh = new Mesh();
|
||||
|
||||
mesh.vertices = vertices;
|
||||
mesh.normals = normals;
|
||||
mesh.SetIndices(indices, MeshTopology.Triangles, 0);
|
||||
|
||||
mesh.name = $"Water collision mesh {i}";
|
||||
|
||||
GameObject go = availableObjects.Count > 0
|
||||
? availableObjects.Dequeue().gameObject
|
||||
: Instantiate(m_waterCollisionPrefab, this.transform);
|
||||
|
||||
go.name = mesh.name;
|
||||
|
||||
go.transform.localPosition = center;
|
||||
go.transform.localRotation = Quaternion.identity;
|
||||
|
||||
var meshCollider = go.GetComponentOrThrow<MeshCollider>();
|
||||
if (meshCollider.sharedMesh != null && !EditorUtilityEx.IsAsset(meshCollider.sharedMesh))
|
||||
F.DestroyEvenInEditMode(meshCollider.sharedMesh);
|
||||
meshCollider.sharedMesh = mesh;
|
||||
|
||||
m_collisionObjects.Add(go.transform);
|
||||
|
||||
i++;
|
||||
}
|
||||
|
||||
foreach (var availableObject in availableObjects)
|
||||
F.DestroyEvenInEditMode(availableObject.gameObject);
|
||||
|
||||
}
|
||||
|
||||
void CreateQuad(Vector2 min, Vector2 max, Vector3[] vertexes, Vector3[] normals, ref int vertexIndex, int[] indexes, ref int indexesIndex)
|
||||
|
|
Loading…
Reference in a new issue