Files
unity-iso-tools/Assets/IsoTools/Scripts/IsoObject.cs
2016-12-30 02:02:47 +07:00

357 lines
8.8 KiB
C#

using UnityEngine;
using IsoTools.Internal;
using System.Collections.Generic;
namespace IsoTools {
[SelectionBase]
[ExecuteInEditMode, DisallowMultipleComponent]
public sealed class IsoObject : IsoObjectBase {
// ---------------------------------------------------------------------
//
// Size
//
// ---------------------------------------------------------------------
[SerializeField]
Vector3 _size = Vector3.one;
public Vector3 size {
get { return _size; }
set {
_size = IsoUtils.Vec3Max(value, Vector3.zero);
FixTransform();
}
}
public float sizeX {
get { return size.x; }
set { size = IsoUtils.Vec3ChangeX(size, value); }
}
public float sizeY {
get { return size.y; }
set { size = IsoUtils.Vec3ChangeY(size, value); }
}
public float sizeZ {
get { return size.z; }
set { size = IsoUtils.Vec3ChangeZ(size, value); }
}
public Vector2 sizeXY {
get { return new Vector2(sizeX, sizeY); }
}
public Vector2 sizeYZ {
get { return new Vector2(sizeY, sizeZ); }
}
public Vector2 sizeXZ {
get { return new Vector2(sizeX, sizeZ); }
}
// ---------------------------------------------------------------------
//
// Position
//
// ---------------------------------------------------------------------
[SerializeField]
Vector3 _position = Vector3.zero;
public Vector3 position {
get { return _position; }
set {
_position = value;
FixTransform();
}
}
public float positionX {
get { return position.x; }
set { position = IsoUtils.Vec3ChangeX(position, value); }
}
public float positionY {
get { return position.y; }
set { position = IsoUtils.Vec3ChangeY(position, value); }
}
public float positionZ {
get { return position.z; }
set { position = IsoUtils.Vec3ChangeZ(position, value); }
}
public Vector2 positionXY {
get { return new Vector2(positionX, positionY); }
set { position = IsoUtils.Vec3ChangeXY(position, value.x, value.y); }
}
public Vector2 positionYZ {
get { return new Vector2(positionY, positionZ); }
set { position = IsoUtils.Vec3ChangeYZ(position, value.x, value.y); }
}
public Vector2 positionXZ {
get { return new Vector2(positionX, positionZ); }
set { position = IsoUtils.Vec3ChangeXZ(position, value.x, value.y); }
}
// ---------------------------------------------------------------------
//
// TilePosition
//
// ---------------------------------------------------------------------
public Vector3 tilePosition {
get { return IsoUtils.Vec3Round(position); }
set { position = value; }
}
public float tilePositionX {
get { return tilePosition.x; }
set { tilePosition = IsoUtils.Vec3ChangeX(tilePosition, value); }
}
public float tilePositionY {
get { return tilePosition.y; }
set { tilePosition = IsoUtils.Vec3ChangeY(tilePosition, value); }
}
public float tilePositionZ {
get { return tilePosition.z; }
set { tilePosition = IsoUtils.Vec3ChangeZ(tilePosition, value); }
}
public Vector2 tilePositionXY {
get { return new Vector2(tilePositionX, tilePositionY); }
}
public Vector2 tilePositionYZ {
get { return new Vector2(tilePositionY, tilePositionZ); }
}
public Vector2 tilePositionXZ {
get { return new Vector2(tilePositionX, tilePositionZ); }
}
// ---------------------------------------------------------------------
//
// Renderers mode
//
// ---------------------------------------------------------------------
public enum RenderersMode {
Mode2d,
Mode3d
}
[SerializeField]
RenderersMode _renderersMode = RenderersMode.Mode2d;
public RenderersMode renderersMode {
get { return _renderersMode; }
set {
_renderersMode = value;
FixTransform();
}
}
// ---------------------------------------------------------------------
//
// Cache renderers
//
// ---------------------------------------------------------------------
[SerializeField]
bool _cachedRenderers = false;
public bool isCachedRenderers {
get { return _cachedRenderers; }
set {
_cachedRenderers = value;
if ( value ) {
UpdateCachedRenderers();
} else {
ClearCachedRenderers();
}
FixTransform();
}
}
// ---------------------------------------------------------------------
//
// Internal
//
// ---------------------------------------------------------------------
public class InternalState {
public bool Dirty = true;
public bool Placed = true;
public IsoQuadTree<IsoObject>.IItem QTItem = null;
public IsoRect QTBounds = IsoRect.zero;
public IsoMinMax MinMax3d = IsoMinMax.zero;
public float Offset3d = 0.0f;
public Transform Transform = null;
public List<Renderer> Renderers = new List<Renderer>();
public IsoAssocList<IsoObject> SelfDepends = new IsoAssocList<IsoObject>(47);
public IsoAssocList<IsoObject> TheirDepends = new IsoAssocList<IsoObject>(47);
}
public InternalState Internal = new InternalState();
// ---------------------------------------------------------------------
//
// Public
//
// ---------------------------------------------------------------------
public void FixTransform() {
var iso_world = isoWorld;
var cached_transform = FixCachedTransform();
if ( iso_world && cached_transform ) {
cached_transform.position = IsoUtils.Vec3ChangeZ(
iso_world.IsoToScreen(position),
cached_transform.position.z);
FixScreenBounds();
MartDirtyIsoWorld();
}
}
public void FixIsoPosition() {
var iso_world = isoWorld;
var cached_transform = FixCachedTransform();
if ( iso_world && cached_transform ) {
position = iso_world.ScreenToIso(
cached_transform.position,
positionZ);
}
}
public void UpdateCachedRenderers() {
GetComponentsInChildren<Renderer>(Internal.Renderers);
}
public void ClearCachedRenderers() {
Internal.Renderers.Clear();
}
// ---------------------------------------------------------------------
//
// Private
//
// ---------------------------------------------------------------------
void FixScreenBounds() {
var iso_world = isoWorld;
if ( iso_world ) {
var l = iso_world.IsoToScreen(position + IsoUtils.Vec3FromY(size.y)).x;
var r = iso_world.IsoToScreen(position + IsoUtils.Vec3FromX(size.x)).x;
var b = iso_world.IsoToScreen(position).y;
var t = iso_world.IsoToScreen(position + size).y;
Internal.QTBounds.Set(l, b, r, t);
} else {
Internal.QTBounds.Set(0.0f, 0.0f, 0.0f, 0.0f);
}
}
Transform FixCachedTransform() {
var ret_value = Internal.Transform;
if ( !ret_value ) {
ret_value = Internal.Transform = transform;
}
return ret_value;
}
void MartDirtyIsoWorld() {
var iso_world = isoWorld;
if ( iso_world ) {
iso_world.Internal_MarkDirty(this);
}
Internal_SetDirtyInEditorMode();
}
// ---------------------------------------------------------------------
//
// Messages
//
// ---------------------------------------------------------------------
void Awake() {
FixCachedTransform();
FixTransform();
}
protected override void OnEnable() {
base.OnEnable();
MartDirtyIsoWorld();
}
protected override void OnDisable() {
base.OnDisable();
}
protected override void OnTransformParentChanged() {
base.OnTransformParentChanged();
FixCachedTransform();
FixTransform();
}
#if UNITY_EDITOR
void Reset() {
size = Vector3.one;
position = Vector3.zero;
renderersMode = RenderersMode.Mode2d;
isCachedRenderers = false;
}
void OnValidate() {
size = _size;
position = _position;
renderersMode = _renderersMode;
isCachedRenderers = _cachedRenderers;
}
void OnDrawGizmos() {
var iso_world = isoWorld;
if ( iso_world ) {
if ( iso_world.isShowIsoBounds ) {
IsoUtils.DrawIsoCube(
iso_world,
position + size * 0.5f,
size,
Color.red);
}
if ( iso_world.isShowScreenBounds ) {
IsoUtils.DrawRect(
Internal.QTBounds,
Color.green);
}
}
}
void OnDrawGizmosSelected() {
var iso_world = isoWorld;
if ( iso_world && iso_world.isShowDepends ) {
for ( int i = 0, e = Internal.SelfDepends.Count; i < e; ++i ) {
IsoUtils.DrawLine(
Internal.QTBounds.center,
Internal.SelfDepends[i].Internal.QTBounds.center,
Color.yellow,
Color.cyan,
0.25f);
}
for ( int i = 0, e = Internal.TheirDepends.Count; i < e; ++i ) {
IsoUtils.DrawLine(
Internal.QTBounds.center,
Internal.TheirDepends[i].Internal.QTBounds.center,
Color.yellow,
Color.cyan,
0.75f);
}
}
}
#endif
}
}