Синтаксис:
Используется csharp
using System;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using UnityEngine.Scripting;
using UnityEngine;
[System.Serializable]
public struct MyBounds
{
private Vector3 m_Center;
private Vector3 m_Extents;
private Quaternion m_Rotation;
public MyBounds(Vector3 center, Quaternion rotation, Vector3 size)
{
this.m_Center = center;
this.m_Extents = (Vector3)(size * 0.5f);
this.m_Rotation = rotation;
}
public override int GetHashCode()
{
return (this.center.GetHashCode() ^ (this.extents.GetHashCode() << 2));
}
public override bool Equals(object other)
{
if (!(other is MyBounds))
{
return false;
}
MyBounds MyBounds = (MyBounds)other;
return (this.center.Equals(MyBounds.center) && this.extents.Equals(MyBounds.extents) && this.rotation.Equals(MyBounds.rotation));
}
public Vector3 center
{
get
{
return this.m_Center;
}
set
{
this.m_Center = value;
}
}
public Quaternion rotation
{
get
{
return this.m_Rotation;
}
set
{
this.m_Rotation = value;
}
}
public Vector3 size
{
get
{
return ((Vector3)(this.m_Extents * 2f));
}
set
{
this.m_Extents = (Vector3)(value * 0.5f);
}
}
public Vector3 extents
{
get
{
return this.m_Extents;
}
set
{
this.m_Extents = value;
}
}
public Vector3 min
{
get
{
return (this.center - this.extents);
}
set
{
this.SetMinMax(value, this.max);
}
}
public Vector3 max
{
get
{
return (this.center + this.extents);
}
set
{
this.SetMinMax(this.min, value);
}
}
public void SetMinMax(Vector3 min, Vector3 max)
{
this.extents = (Vector3)((max - min) * 0.5f);
this.center = min + this.extents;
}
public void Encapsulate(Vector3 point)
{
this.SetMinMax(Vector3.Min(this.min, point), Vector3.Max(this.max, point));
}
public void Encapsulate(MyBounds MyBounds)
{
this.Encapsulate(MyBounds.center - MyBounds.extents);
this.Encapsulate(MyBounds.center + MyBounds.extents);
}
public void Expand(float amount)
{
amount *= 0.5f;
this.extents += new Vector3(amount, amount, amount);
}
public void Expand(Vector3 amount)
{
this.extents += (Vector3)(amount * 0.5f);
}
public bool Intersects(MyBounds MyBounds)
{
Vector3 EulerRot = rotation.eulerAngles;
Vector3 EulerRot2 = MyBounds.rotation.eulerAngles;
return (((((this.min.x+EulerRot.x <= MyBounds.max.x+EulerRot2.x) && (this.max.x+EulerRot.x >= MyBounds.min.x+EulerRot2.x)) && ((this.min.y+EulerRot.y <= MyBounds.max.y+EulerRot2.y) && (this.max.y+EulerRot.y >= MyBounds.min.y+EulerRot2.y))) && (this.min.z+EulerRot.z <= MyBounds.max.z+EulerRot2.z)) && (this.max.z+EulerRot.z >= MyBounds.min.z+EulerRot2.z));
}
private static bool Internal_Contains(MyBounds m, Vector3 point)
{
return INTERNAL_CALL_Internal_Contains(ref m, ref point);
}
[MethodImpl(MethodImplOptions.InternalCall)]
private static extern bool INTERNAL_CALL_Internal_Contains(ref MyBounds m, ref Vector3 point);
public bool Contains(Vector3 point)
{
return Internal_Contains(this, point);
}
private static float Internal_SqrDistance(MyBounds m, Vector3 point)
{
return INTERNAL_CALL_Internal_SqrDistance(ref m, ref point);
}
[MethodImpl(MethodImplOptions.InternalCall)]
private static extern float INTERNAL_CALL_Internal_SqrDistance(ref MyBounds m, ref Vector3 point);
public float SqrDistance(Vector3 point)
{
return Internal_SqrDistance(this, point);
}
private static bool Internal_IntersectRay(ref Ray ray, ref MyBounds MyBounds, out float distance)
{
return INTERNAL_CALL_Internal_IntersectRay(ref ray, ref MyBounds, out distance);
}
[MethodImpl(MethodImplOptions.InternalCall)]
private static extern bool INTERNAL_CALL_Internal_IntersectRay(ref Ray ray, ref MyBounds MyBounds, out float distance);
public bool IntersectRay(Ray ray)
{
float num;
return Internal_IntersectRay(ref ray, ref this, out num);
}
public bool IntersectRay(Ray ray, out float distance)
{
return Internal_IntersectRay(ref ray, ref this, out distance);
}
private static Vector3 Internal_GetClosestPoint(ref MyBounds MyBounds, ref Vector3 point)
{
Vector3 vector;
INTERNAL_CALL_Internal_GetClosestPoint(ref MyBounds, ref point, out vector);
return vector;
}
[MethodImpl(MethodImplOptions.InternalCall)]
private static extern void INTERNAL_CALL_Internal_GetClosestPoint(ref MyBounds MyBounds, ref Vector3 point, out Vector3 value);
public Vector3 ClosestPoint(Vector3 point)
{
return Internal_GetClosestPoint(ref this, ref point);
}
public override string ToString()
{
object[] args = new object[] { this.m_Center, this.m_Extents };
return String.Format("Center: {0}, Extents: {1}", args);
}
public string ToString(string format)
{
object[] args = new object[] { this.m_Center.ToString(format), this.m_Extents.ToString(format) };
return String.Format("Center: {0}, Extents: {1}", args);
}
public static bool operator ==(MyBounds lhs, MyBounds rhs)
{
return ((lhs.center == rhs.center) && (lhs.extents == rhs.extents));
}
public static bool operator !=(MyBounds lhs, MyBounds rhs)
{
return !(lhs == rhs);
}
}
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using UnityEngine.Scripting;
using UnityEngine;
[System.Serializable]
public struct MyBounds
{
private Vector3 m_Center;
private Vector3 m_Extents;
private Quaternion m_Rotation;
public MyBounds(Vector3 center, Quaternion rotation, Vector3 size)
{
this.m_Center = center;
this.m_Extents = (Vector3)(size * 0.5f);
this.m_Rotation = rotation;
}
public override int GetHashCode()
{
return (this.center.GetHashCode() ^ (this.extents.GetHashCode() << 2));
}
public override bool Equals(object other)
{
if (!(other is MyBounds))
{
return false;
}
MyBounds MyBounds = (MyBounds)other;
return (this.center.Equals(MyBounds.center) && this.extents.Equals(MyBounds.extents) && this.rotation.Equals(MyBounds.rotation));
}
public Vector3 center
{
get
{
return this.m_Center;
}
set
{
this.m_Center = value;
}
}
public Quaternion rotation
{
get
{
return this.m_Rotation;
}
set
{
this.m_Rotation = value;
}
}
public Vector3 size
{
get
{
return ((Vector3)(this.m_Extents * 2f));
}
set
{
this.m_Extents = (Vector3)(value * 0.5f);
}
}
public Vector3 extents
{
get
{
return this.m_Extents;
}
set
{
this.m_Extents = value;
}
}
public Vector3 min
{
get
{
return (this.center - this.extents);
}
set
{
this.SetMinMax(value, this.max);
}
}
public Vector3 max
{
get
{
return (this.center + this.extents);
}
set
{
this.SetMinMax(this.min, value);
}
}
public void SetMinMax(Vector3 min, Vector3 max)
{
this.extents = (Vector3)((max - min) * 0.5f);
this.center = min + this.extents;
}
public void Encapsulate(Vector3 point)
{
this.SetMinMax(Vector3.Min(this.min, point), Vector3.Max(this.max, point));
}
public void Encapsulate(MyBounds MyBounds)
{
this.Encapsulate(MyBounds.center - MyBounds.extents);
this.Encapsulate(MyBounds.center + MyBounds.extents);
}
public void Expand(float amount)
{
amount *= 0.5f;
this.extents += new Vector3(amount, amount, amount);
}
public void Expand(Vector3 amount)
{
this.extents += (Vector3)(amount * 0.5f);
}
public bool Intersects(MyBounds MyBounds)
{
Vector3 EulerRot = rotation.eulerAngles;
Vector3 EulerRot2 = MyBounds.rotation.eulerAngles;
return (((((this.min.x+EulerRot.x <= MyBounds.max.x+EulerRot2.x) && (this.max.x+EulerRot.x >= MyBounds.min.x+EulerRot2.x)) && ((this.min.y+EulerRot.y <= MyBounds.max.y+EulerRot2.y) && (this.max.y+EulerRot.y >= MyBounds.min.y+EulerRot2.y))) && (this.min.z+EulerRot.z <= MyBounds.max.z+EulerRot2.z)) && (this.max.z+EulerRot.z >= MyBounds.min.z+EulerRot2.z));
}
private static bool Internal_Contains(MyBounds m, Vector3 point)
{
return INTERNAL_CALL_Internal_Contains(ref m, ref point);
}
[MethodImpl(MethodImplOptions.InternalCall)]
private static extern bool INTERNAL_CALL_Internal_Contains(ref MyBounds m, ref Vector3 point);
public bool Contains(Vector3 point)
{
return Internal_Contains(this, point);
}
private static float Internal_SqrDistance(MyBounds m, Vector3 point)
{
return INTERNAL_CALL_Internal_SqrDistance(ref m, ref point);
}
[MethodImpl(MethodImplOptions.InternalCall)]
private static extern float INTERNAL_CALL_Internal_SqrDistance(ref MyBounds m, ref Vector3 point);
public float SqrDistance(Vector3 point)
{
return Internal_SqrDistance(this, point);
}
private static bool Internal_IntersectRay(ref Ray ray, ref MyBounds MyBounds, out float distance)
{
return INTERNAL_CALL_Internal_IntersectRay(ref ray, ref MyBounds, out distance);
}
[MethodImpl(MethodImplOptions.InternalCall)]
private static extern bool INTERNAL_CALL_Internal_IntersectRay(ref Ray ray, ref MyBounds MyBounds, out float distance);
public bool IntersectRay(Ray ray)
{
float num;
return Internal_IntersectRay(ref ray, ref this, out num);
}
public bool IntersectRay(Ray ray, out float distance)
{
return Internal_IntersectRay(ref ray, ref this, out distance);
}
private static Vector3 Internal_GetClosestPoint(ref MyBounds MyBounds, ref Vector3 point)
{
Vector3 vector;
INTERNAL_CALL_Internal_GetClosestPoint(ref MyBounds, ref point, out vector);
return vector;
}
[MethodImpl(MethodImplOptions.InternalCall)]
private static extern void INTERNAL_CALL_Internal_GetClosestPoint(ref MyBounds MyBounds, ref Vector3 point, out Vector3 value);
public Vector3 ClosestPoint(Vector3 point)
{
return Internal_GetClosestPoint(ref this, ref point);
}
public override string ToString()
{
object[] args = new object[] { this.m_Center, this.m_Extents };
return String.Format("Center: {0}, Extents: {1}", args);
}
public string ToString(string format)
{
object[] args = new object[] { this.m_Center.ToString(format), this.m_Extents.ToString(format) };
return String.Format("Center: {0}, Extents: {1}", args);
}
public static bool operator ==(MyBounds lhs, MyBounds rhs)
{
return ((lhs.center == rhs.center) && (lhs.extents == rhs.extents));
}
public static bool operator !=(MyBounds lhs, MyBounds rhs)
{
return !(lhs == rhs);
}
}
И два класса - BlockStats и BlockStatsEditor.
Синтаксис:
Используется csharp
using UnityEngine;
using System.Collections;
public class BlockStats : MonoBehaviour {
public int strengthBlock;
public float PlaceEnergyCost;
Collider Collider;
[SerializeField]
public MyBounds BlockBounds;
public bool AllowToPlace;
public bool Placed;
public Material BeforePlaceMaterial;
public Material AfterPlaceMaterial;
public bool CustomConstantRotation;
void Start()
{
Collider = GetComponent<Collider>();
if (BeforePlaceMaterial)
GetComponent<MeshRenderer>().material = BeforePlaceMaterial;
}
bool updateAfterPlaced;
void Update()
{
if (!CustomConstantRotation)
{
BlockBounds.rotation = transform.rotation;
}
if (!Placed)
{
bool intersects = false;
Collider[] hits = Physics.OverlapBox(transform.position, BlockBounds.extents * 0.9f);
for (int i = 0; i < hits.Length; i++)
{
if (hits[i].transform.GetComponent<BlockStats>())
if (BlockBounds.Intersects(hits[i].transform.GetComponent<BlockStats>().BlockBounds) && hits[i].transform != transform)
intersects = true;
}
if (intersects)
{
AllowToPlace = false;
}
else
{
AllowToPlace = true;
}
if (!AllowToPlace)
{
GetComponent<MeshRenderer>().material.color = new Color(1, 0, 0, 0.3f);
}
else
{
GetComponent<MeshRenderer>().material.color = new Color(0, 1, 0, 0.3f);
}
}
if (Placed)
{
if (!updateAfterPlaced)
{
GetComponent<MeshRenderer>().material = AfterPlaceMaterial;
GetComponent<Collider>().isTrigger = false;
gameObject.AddComponent<Rigidbody>();
updateAfterPlaced = true;
}
}
}
void OnTriggerStay(Collider col)
{
if (!Placed)
{
AllowToPlace = false;
}
}
void OnTriggerExit(Collider col)
{
if (!Placed)
{
AllowToPlace = true;
}
}
}
using System.Collections;
public class BlockStats : MonoBehaviour {
public int strengthBlock;
public float PlaceEnergyCost;
Collider Collider;
[SerializeField]
public MyBounds BlockBounds;
public bool AllowToPlace;
public bool Placed;
public Material BeforePlaceMaterial;
public Material AfterPlaceMaterial;
public bool CustomConstantRotation;
void Start()
{
Collider = GetComponent<Collider>();
if (BeforePlaceMaterial)
GetComponent<MeshRenderer>().material = BeforePlaceMaterial;
}
bool updateAfterPlaced;
void Update()
{
if (!CustomConstantRotation)
{
BlockBounds.rotation = transform.rotation;
}
if (!Placed)
{
bool intersects = false;
Collider[] hits = Physics.OverlapBox(transform.position, BlockBounds.extents * 0.9f);
for (int i = 0; i < hits.Length; i++)
{
if (hits[i].transform.GetComponent<BlockStats>())
if (BlockBounds.Intersects(hits[i].transform.GetComponent<BlockStats>().BlockBounds) && hits[i].transform != transform)
intersects = true;
}
if (intersects)
{
AllowToPlace = false;
}
else
{
AllowToPlace = true;
}
if (!AllowToPlace)
{
GetComponent<MeshRenderer>().material.color = new Color(1, 0, 0, 0.3f);
}
else
{
GetComponent<MeshRenderer>().material.color = new Color(0, 1, 0, 0.3f);
}
}
if (Placed)
{
if (!updateAfterPlaced)
{
GetComponent<MeshRenderer>().material = AfterPlaceMaterial;
GetComponent<Collider>().isTrigger = false;
gameObject.AddComponent<Rigidbody>();
updateAfterPlaced = true;
}
}
}
void OnTriggerStay(Collider col)
{
if (!Placed)
{
AllowToPlace = false;
}
}
void OnTriggerExit(Collider col)
{
if (!Placed)
{
AllowToPlace = true;
}
}
}
Синтаксис:
Используется csharp
#if UNITY_EDITOR
using UnityEngine;
using System.Collections;
using UnityEditor;
[CustomEditor(typeof(BlockStats))]
public class BlockStatsEditor : Editor {
// Use this for initialization
void Start () {
}
// Update is called once per frame
void Update () {
}
public override void OnInspectorGUI()
{
BlockStats blockStats = (BlockStats)target;
EditorGUILayout.BeginVertical(new GUIStyle("box"));
EditorGUILayout.LabelField("Block Bounds");
blockStats.BlockBounds.center = EditorGUILayout.Vector3Field("Center", blockStats.BlockBounds.center);
blockStats.BlockBounds.extents = EditorGUILayout.Vector3Field("Extents (half-size of real scale)", blockStats.BlockBounds.extents);
blockStats.CustomConstantRotation = EditorGUILayout.Toggle("Uses custom constant rotation",blockStats.CustomConstantRotation);
if (blockStats.CustomConstantRotation)
{
blockStats.BlockBounds.rotation = Quaternion.Euler(EditorGUILayout.Vector3Field("Rotation (in Euler angles)", blockStats.BlockBounds.rotation.eulerAngles));
}
EditorGUILayout.EndVertical();
blockStats.BeforePlaceMaterial = (Material)EditorGUILayout.ObjectField("Before place material",blockStats.BeforePlaceMaterial, typeof(Material));
blockStats.AfterPlaceMaterial = (Material)EditorGUILayout.ObjectField("After place material",blockStats.AfterPlaceMaterial, typeof(Material));
blockStats.PlaceEnergyCost = EditorGUILayout.FloatField("Place energy cost", blockStats.PlaceEnergyCost);
}
}
#endif
using UnityEngine;
using System.Collections;
using UnityEditor;
[CustomEditor(typeof(BlockStats))]
public class BlockStatsEditor : Editor {
// Use this for initialization
void Start () {
}
// Update is called once per frame
void Update () {
}
public override void OnInspectorGUI()
{
BlockStats blockStats = (BlockStats)target;
EditorGUILayout.BeginVertical(new GUIStyle("box"));
EditorGUILayout.LabelField("Block Bounds");
blockStats.BlockBounds.center = EditorGUILayout.Vector3Field("Center", blockStats.BlockBounds.center);
blockStats.BlockBounds.extents = EditorGUILayout.Vector3Field("Extents (half-size of real scale)", blockStats.BlockBounds.extents);
blockStats.CustomConstantRotation = EditorGUILayout.Toggle("Uses custom constant rotation",blockStats.CustomConstantRotation);
if (blockStats.CustomConstantRotation)
{
blockStats.BlockBounds.rotation = Quaternion.Euler(EditorGUILayout.Vector3Field("Rotation (in Euler angles)", blockStats.BlockBounds.rotation.eulerAngles));
}
EditorGUILayout.EndVertical();
blockStats.BeforePlaceMaterial = (Material)EditorGUILayout.ObjectField("Before place material",blockStats.BeforePlaceMaterial, typeof(Material));
blockStats.AfterPlaceMaterial = (Material)EditorGUILayout.ObjectField("After place material",blockStats.AfterPlaceMaterial, typeof(Material));
blockStats.PlaceEnergyCost = EditorGUILayout.FloatField("Place energy cost", blockStats.PlaceEnergyCost);
}
}
#endif
При заходе в игру параметры struct не сохраняются, способы "System.Serializable" и "SerializeField" не помогают. Что делать?
И каким образом вычислить размер границ с учётом их поворота? ( то есть, повёрнутые границы )
Синтаксис:
Используется csharp
Vector3 bObjectPos;
RaycastHit hit;
BlockStats bls;
private void BuildUpdate()
{
if (buildModeActive)
{
if (SelectedBuildObject.GetComponent<BlockStats>())
{
if (Physics.Raycast(cam.transform.position, cam.transform.forward, out hit, 20) && hit.transform.tag == "Buildable" | hit.transform.GetComponentInParent<TerrainVolume>())
{
if (!buildObject)
{
BlockStats bls = SelectedBuildObject.GetComponent<BlockStats>();
Vector3 EulerBlockRot = bls.BlockBounds.rotation.eulerAngles;
if (!BuildCenterMode || hit.transform.GetComponentInParent<TerrainVolume>())
{
InstantStepCell();
}
else
{
bObjectPos = hit.collider.transform.position;
if (hit.normal.x > 0) { bObjectPos.x = hit.collider.transform.position.x + hit.collider.bounds.extents.x + bls.BlockBounds.extents.x; }
else if (hit.normal.x < 0) { bObjectPos.x = hit.collider.transform.position.x - hit.collider.bounds.extents.x - bls.BlockBounds.extents.x; }
else if (hit.normal.y > 0) { bObjectPos.y = hit.collider.transform.position.y + hit.collider.bounds.extents.y + bls.BlockBounds.extents.y; }
else if (hit.normal.y < 0) { bObjectPos.y = hit.collider.transform.position.y - hit.collider.bounds.extents.y - bls.BlockBounds.extents.y; }
else if (hit.normal.z > 0) { bObjectPos.z = hit.collider.transform.position.z + hit.collider.bounds.extents.z + bls.BlockBounds.extents.z; }
else if (hit.normal.z < 0) { bObjectPos.z = hit.collider.transform.position.z - hit.collider.bounds.extents.z - bls.BlockBounds.extents.z; }
}
buildObject = (GameObject)Instantiate(SelectedBuildObject, bObjectPos, new Quaternion());
buildObject.transform.rotation = hit.transform.rotation;
buildObject.layer = 2;
}
else
{
bObjectPos = hit.point;
bls = SelectedBuildObject.GetComponent<BlockStats>();
Vector3 EulerBlockRot = SelectedBuildObject.transform.rotation.eulerAngles;
if (!BuildCenterMode || hit.transform.GetComponentInParent<TerrainVolume>())
{
InstantStepCell();
}
else
{
bObjectPos = hit.collider.transform.position;
if (hit.normal.x > 0) { bObjectPos.x = hit.collider.transform.position.x + hit.collider.bounds.extents.x + bls.BlockBounds.extents.x; }
else if (hit.normal.x < 0) { bObjectPos.x = hit.collider.transform.position.x - hit.collider.bounds.extents.x - bls.BlockBounds.extents.x; }
else if (hit.normal.y > 0) { bObjectPos.y = hit.collider.transform.position.y + hit.collider.bounds.extents.y + bls.BlockBounds.extents.y; }
else if (hit.normal.y < 0) { bObjectPos.y = hit.collider.transform.position.y - hit.collider.bounds.extents.y - bls.BlockBounds.extents.y; }
else if (hit.normal.z > 0) { bObjectPos.z = hit.collider.transform.position.z + hit.collider.bounds.extents.z + bls.BlockBounds.extents.z; }
else if (hit.normal.z < 0) { bObjectPos.z = hit.collider.transform.position.z - hit.collider.bounds.extents.z - bls.BlockBounds.extents.z; }
}
buildObject.transform.position = bObjectPos;
buildObject.transform.rotation = hit.transform.rotation;
}
if (Input.GetMouseButtonDown(0))
{
if (buildObject.GetComponent<BlockStats>().AllowToPlace)
{
buildObject.GetComponent<BlockStats>().Placed = true;
if (hit.transform.GetComponentInParent<Grid>())
{
buildObject.transform.parent = hit.transform.GetComponentInParent<Grid>().transform;
hit.transform.GetComponentInParent<Grid>().BuildPrefabs.Add(buildObject.GetComponent<BlockStats>());
}
else
{
GameObject GridObject = new GameObject("New Grid");
GridObject.AddComponent<Grid>().GridName = "New Grid";
GridObject.GetComponent<Grid>().BuildPrefabs.Add(buildObject.GetComponent<BlockStats>());
buildObject.transform.parent = GridObject.transform;
}
buildObject.layer = 0;
buildObject = null;
}
}
}
else
{
if (buildObject) { Destroy(buildObject); buildObject = null; }
}
}
else
{
if (buildObject)
{
Destroy(buildObject); buildObject = null;
}
}
}
else
{
if (buildObject)
{
Destroy(buildObject);
buildObject = null;
}
}
}
void InstantStepCell()
{
if (bls != null)
{
if (!hit.transform.GetComponentInParent<TerrainVolume>())
{
if (hit.transform.GetComponent<BlockStats>())
{
bObjectPos = hit.point;
//если устанавливаем на верхнюю сторону, то прибавляем размеры установленного и устанавливаемого объекта
if (hit.normal.y > 0)
{
bObjectPos.y = hit.collider.transform.position.y + hit.transform.GetComponent<BlockStats>().BlockBounds.extents.y + bls.BlockBounds.extents.y;
bObjectPos.x = StepCell(bObjectPos.x);
bObjectPos.z = StepCell(bObjectPos.z);
} //если на нижнюю то отнимаем размеры установленного и устанавливаемого объекта по Y
else if (hit.normal.y < 0)
{
bObjectPos.y = hit.collider.transform.position.y - hit.transform.GetComponent<BlockStats>().BlockBounds.extents.y - bls.BlockBounds.extents.y;
bObjectPos.x = StepCell(bObjectPos.x);
bObjectPos.z = StepCell(bObjectPos.z);
}
else if (hit.normal.x > 0)
{
bObjectPos.x = hit.collider.transform.position.x + hit.transform.GetComponent<BlockStats>().BlockBounds.extents.x + bls.BlockBounds.extents.x;
bObjectPos.y = StepCell(bObjectPos.y);
bObjectPos.z = StepCell(bObjectPos.z);
}
else if (hit.normal.x < 0)
{
bObjectPos.x = hit.collider.transform.position.x - hit.transform.GetComponent<BlockStats>().BlockBounds.extents.x - bls.BlockBounds.extents.x;
bObjectPos.y = StepCell(bObjectPos.y);
bObjectPos.z = StepCell(bObjectPos.z);
}
else if (hit.normal.z > 0)
{
bObjectPos.z = hit.collider.transform.position.z + hit.transform.GetComponent<BlockStats>().BlockBounds.extents.z + bls.BlockBounds.extents.z;
bObjectPos.y = StepCell(bObjectPos.y);
bObjectPos.x = StepCell(bObjectPos.x);
}
else if (hit.normal.z < 0)
{
bObjectPos.z = hit.collider.transform.position.z - hit.transform.GetComponent<BlockStats>().BlockBounds.extents.z - bls.BlockBounds.extents.z;
bObjectPos.y = StepCell(bObjectPos.y);
bObjectPos.x = StepCell(bObjectPos.x);
}
}
}
else
{
bObjectPos = hit.point;
//если устанавливаем на верхнюю сторону, то прибавляем размеры установленного и устанавливаемого объекта
if (hit.normal.y > 0)
{
Debug.Log(bls != null);
Debug.Log(bls.BlockBounds != null);
bObjectPos.y = hit.point.y + bls.BlockBounds.extents.y;
bObjectPos.x = StepCell(bObjectPos.x);
bObjectPos.z = StepCell(bObjectPos.z);
} //если на нижнюю то отнимаем размеры установленного и устанавливаемого объекта по Y
else if (hit.normal.y < 0)
{
bObjectPos.y = hit.point.y - bls.BlockBounds.extents.y;
bObjectPos.x = StepCell(bObjectPos.x);
bObjectPos.z = StepCell(bObjectPos.z);
}
else if (hit.normal.x > 0)
{
bObjectPos.x = hit.point.x + bls.BlockBounds.extents.x;
bObjectPos.y = StepCell(bObjectPos.y);
bObjectPos.z = StepCell(bObjectPos.z);
}
else if (hit.normal.x < 0)
{
bObjectPos.x = hit.point.x - bls.BlockBounds.extents.x;
bObjectPos.y = StepCell(bObjectPos.y);
bObjectPos.z = StepCell(bObjectPos.z);
}
else if (hit.normal.z > 0)
{
bObjectPos.z = hit.point.z + bls.BlockBounds.extents.z;
bObjectPos.y = StepCell(bObjectPos.y);
bObjectPos.x = StepCell(bObjectPos.x);
}
else if (hit.normal.z < 0)
{
bObjectPos.z = hit.point.z - bls.BlockBounds.extents.z;
bObjectPos.y = StepCell(bObjectPos.y);
bObjectPos.x = StepCell(bObjectPos.x);
}
}
}
}
float StepCell(float coord)
{
coord = (Mathf.Round(coord / 0.125f)) * 0.125f;
return coord;
}
RaycastHit hit;
BlockStats bls;
private void BuildUpdate()
{
if (buildModeActive)
{
if (SelectedBuildObject.GetComponent<BlockStats>())
{
if (Physics.Raycast(cam.transform.position, cam.transform.forward, out hit, 20) && hit.transform.tag == "Buildable" | hit.transform.GetComponentInParent<TerrainVolume>())
{
if (!buildObject)
{
BlockStats bls = SelectedBuildObject.GetComponent<BlockStats>();
Vector3 EulerBlockRot = bls.BlockBounds.rotation.eulerAngles;
if (!BuildCenterMode || hit.transform.GetComponentInParent<TerrainVolume>())
{
InstantStepCell();
}
else
{
bObjectPos = hit.collider.transform.position;
if (hit.normal.x > 0) { bObjectPos.x = hit.collider.transform.position.x + hit.collider.bounds.extents.x + bls.BlockBounds.extents.x; }
else if (hit.normal.x < 0) { bObjectPos.x = hit.collider.transform.position.x - hit.collider.bounds.extents.x - bls.BlockBounds.extents.x; }
else if (hit.normal.y > 0) { bObjectPos.y = hit.collider.transform.position.y + hit.collider.bounds.extents.y + bls.BlockBounds.extents.y; }
else if (hit.normal.y < 0) { bObjectPos.y = hit.collider.transform.position.y - hit.collider.bounds.extents.y - bls.BlockBounds.extents.y; }
else if (hit.normal.z > 0) { bObjectPos.z = hit.collider.transform.position.z + hit.collider.bounds.extents.z + bls.BlockBounds.extents.z; }
else if (hit.normal.z < 0) { bObjectPos.z = hit.collider.transform.position.z - hit.collider.bounds.extents.z - bls.BlockBounds.extents.z; }
}
buildObject = (GameObject)Instantiate(SelectedBuildObject, bObjectPos, new Quaternion());
buildObject.transform.rotation = hit.transform.rotation;
buildObject.layer = 2;
}
else
{
bObjectPos = hit.point;
bls = SelectedBuildObject.GetComponent<BlockStats>();
Vector3 EulerBlockRot = SelectedBuildObject.transform.rotation.eulerAngles;
if (!BuildCenterMode || hit.transform.GetComponentInParent<TerrainVolume>())
{
InstantStepCell();
}
else
{
bObjectPos = hit.collider.transform.position;
if (hit.normal.x > 0) { bObjectPos.x = hit.collider.transform.position.x + hit.collider.bounds.extents.x + bls.BlockBounds.extents.x; }
else if (hit.normal.x < 0) { bObjectPos.x = hit.collider.transform.position.x - hit.collider.bounds.extents.x - bls.BlockBounds.extents.x; }
else if (hit.normal.y > 0) { bObjectPos.y = hit.collider.transform.position.y + hit.collider.bounds.extents.y + bls.BlockBounds.extents.y; }
else if (hit.normal.y < 0) { bObjectPos.y = hit.collider.transform.position.y - hit.collider.bounds.extents.y - bls.BlockBounds.extents.y; }
else if (hit.normal.z > 0) { bObjectPos.z = hit.collider.transform.position.z + hit.collider.bounds.extents.z + bls.BlockBounds.extents.z; }
else if (hit.normal.z < 0) { bObjectPos.z = hit.collider.transform.position.z - hit.collider.bounds.extents.z - bls.BlockBounds.extents.z; }
}
buildObject.transform.position = bObjectPos;
buildObject.transform.rotation = hit.transform.rotation;
}
if (Input.GetMouseButtonDown(0))
{
if (buildObject.GetComponent<BlockStats>().AllowToPlace)
{
buildObject.GetComponent<BlockStats>().Placed = true;
if (hit.transform.GetComponentInParent<Grid>())
{
buildObject.transform.parent = hit.transform.GetComponentInParent<Grid>().transform;
hit.transform.GetComponentInParent<Grid>().BuildPrefabs.Add(buildObject.GetComponent<BlockStats>());
}
else
{
GameObject GridObject = new GameObject("New Grid");
GridObject.AddComponent<Grid>().GridName = "New Grid";
GridObject.GetComponent<Grid>().BuildPrefabs.Add(buildObject.GetComponent<BlockStats>());
buildObject.transform.parent = GridObject.transform;
}
buildObject.layer = 0;
buildObject = null;
}
}
}
else
{
if (buildObject) { Destroy(buildObject); buildObject = null; }
}
}
else
{
if (buildObject)
{
Destroy(buildObject); buildObject = null;
}
}
}
else
{
if (buildObject)
{
Destroy(buildObject);
buildObject = null;
}
}
}
void InstantStepCell()
{
if (bls != null)
{
if (!hit.transform.GetComponentInParent<TerrainVolume>())
{
if (hit.transform.GetComponent<BlockStats>())
{
bObjectPos = hit.point;
//если устанавливаем на верхнюю сторону, то прибавляем размеры установленного и устанавливаемого объекта
if (hit.normal.y > 0)
{
bObjectPos.y = hit.collider.transform.position.y + hit.transform.GetComponent<BlockStats>().BlockBounds.extents.y + bls.BlockBounds.extents.y;
bObjectPos.x = StepCell(bObjectPos.x);
bObjectPos.z = StepCell(bObjectPos.z);
} //если на нижнюю то отнимаем размеры установленного и устанавливаемого объекта по Y
else if (hit.normal.y < 0)
{
bObjectPos.y = hit.collider.transform.position.y - hit.transform.GetComponent<BlockStats>().BlockBounds.extents.y - bls.BlockBounds.extents.y;
bObjectPos.x = StepCell(bObjectPos.x);
bObjectPos.z = StepCell(bObjectPos.z);
}
else if (hit.normal.x > 0)
{
bObjectPos.x = hit.collider.transform.position.x + hit.transform.GetComponent<BlockStats>().BlockBounds.extents.x + bls.BlockBounds.extents.x;
bObjectPos.y = StepCell(bObjectPos.y);
bObjectPos.z = StepCell(bObjectPos.z);
}
else if (hit.normal.x < 0)
{
bObjectPos.x = hit.collider.transform.position.x - hit.transform.GetComponent<BlockStats>().BlockBounds.extents.x - bls.BlockBounds.extents.x;
bObjectPos.y = StepCell(bObjectPos.y);
bObjectPos.z = StepCell(bObjectPos.z);
}
else if (hit.normal.z > 0)
{
bObjectPos.z = hit.collider.transform.position.z + hit.transform.GetComponent<BlockStats>().BlockBounds.extents.z + bls.BlockBounds.extents.z;
bObjectPos.y = StepCell(bObjectPos.y);
bObjectPos.x = StepCell(bObjectPos.x);
}
else if (hit.normal.z < 0)
{
bObjectPos.z = hit.collider.transform.position.z - hit.transform.GetComponent<BlockStats>().BlockBounds.extents.z - bls.BlockBounds.extents.z;
bObjectPos.y = StepCell(bObjectPos.y);
bObjectPos.x = StepCell(bObjectPos.x);
}
}
}
else
{
bObjectPos = hit.point;
//если устанавливаем на верхнюю сторону, то прибавляем размеры установленного и устанавливаемого объекта
if (hit.normal.y > 0)
{
Debug.Log(bls != null);
Debug.Log(bls.BlockBounds != null);
bObjectPos.y = hit.point.y + bls.BlockBounds.extents.y;
bObjectPos.x = StepCell(bObjectPos.x);
bObjectPos.z = StepCell(bObjectPos.z);
} //если на нижнюю то отнимаем размеры установленного и устанавливаемого объекта по Y
else if (hit.normal.y < 0)
{
bObjectPos.y = hit.point.y - bls.BlockBounds.extents.y;
bObjectPos.x = StepCell(bObjectPos.x);
bObjectPos.z = StepCell(bObjectPos.z);
}
else if (hit.normal.x > 0)
{
bObjectPos.x = hit.point.x + bls.BlockBounds.extents.x;
bObjectPos.y = StepCell(bObjectPos.y);
bObjectPos.z = StepCell(bObjectPos.z);
}
else if (hit.normal.x < 0)
{
bObjectPos.x = hit.point.x - bls.BlockBounds.extents.x;
bObjectPos.y = StepCell(bObjectPos.y);
bObjectPos.z = StepCell(bObjectPos.z);
}
else if (hit.normal.z > 0)
{
bObjectPos.z = hit.point.z + bls.BlockBounds.extents.z;
bObjectPos.y = StepCell(bObjectPos.y);
bObjectPos.x = StepCell(bObjectPos.x);
}
else if (hit.normal.z < 0)
{
bObjectPos.z = hit.point.z - bls.BlockBounds.extents.z;
bObjectPos.y = StepCell(bObjectPos.y);
bObjectPos.x = StepCell(bObjectPos.x);
}
}
}
}
float StepCell(float coord)
{
coord = (Mathf.Round(coord / 0.125f)) * 0.125f;
return coord;
}
Вычислить размер границ с их поворотом я пытался с помощью сложения векторов extents и rotation.eulerAngles ( как, собственно, видно из кода ), но это не даёт нужных мне результатов.
P.S под границами я имею ввиду структуру Bounds, а конкретнее, мою структуру MyBounds.
P.P.S и не судите строго за говнокод, в дальнейшем я всё это исправлю