블로그 이미지
Every unexpected event is a path to learning for you.

카테고리

분류 전체보기 (2737)
Unity3D (817)
Programming (474)
Server (33)
Unreal (4)
Gamebryo (56)
Tip & Tech (228)
협업 (58)
3DS Max (3)
Game (12)
Utility (136)
Etc (96)
Link (32)
Portfolio (19)
Subject (90)
iOS,OSX (53)
Android (14)
Linux (5)
잉여 프로젝트 (2)
게임이야기 (3)
Memories (20)
Interest (38)
Thinking (38)
한글 (30)
PaperCraft (5)
Animation (408)
Wallpaper (2)
재테크 (18)
Exercise (3)
나만의 맛집 (3)
냥이 (10)
육아 (16)
Total
Today
Yesterday
04-21 00:01

Here are two small tricks that can help if you’re making an isometric 2D game in Unity. Ok, so not actually isometric, but that’s the term we’re used to in videogames, so we’ll go with it. These are quite basic and if you’re working on such a game you’ve probably already tackled them your own way. This is our take on it, hopefully it’s useful to someone.

Sprite Ordering

Normally in a 2D game there is no concept of depth, so if you simply place the sprites in the world, you’ll most likely have objects appearing in the wrong order than what you’d expect in an isometric game.

 

Thankfully Unity exposes Sorting Layer and Order In Layer properties for Renderers.
A quick fix is to set the value of Order in Layer to depend on the Y position of the object.

 

[ExecuteInEditMode]
[RequireComponent(typeof(Renderer))]
public class DepthSortByY : MonoBehaviour
{

    private const int IsometricRangePerYUnit = 100;

    void Update()
    {
        Renderer renderer = GetComponent();
        renderer.sortingOrder = -(int)(transform.position.y * IsometricRangePerYUnit);
    }
}

This solves the problem for the simplest case, when we assume all objects rest on the ground.

 

Let’s assume we want to have an object that is above the ground in the world, like placing a bird house on that tree. Just trying to place it in the world will treat the pivot of the object as being at ground level, with no way to both place it at a proper height and sort it correctly.

 

There are several options for this. Just to get it out of the system, the first option is to add empty space to the texture below the bird house to make sure the pivot is at ground level (in Unity, the pivot can’t be outside of the sprite). This is baaaad! This is wasting texture space, and all instances of that object will need to be at the same height in the game. There are other, less insane, options.

One is having a height property in the DepthSortByY behavior and subtract it from transform.position.y when computing the sorting order.
Another solution (which we went with) is allowing the DepthSortByY behavior to make the depth computation based on another object’s transform. This way, the objects will be considered to be at the same point in space as their target and they’ll have the same depth order, even if they’re at different Y positions in the scene. In the bird house example, the bird house uses the tree’s world position for its depth computations.
This solution works better for our game, because it allows artists to move the item freely while staying at the depth (and not have to deal with editing the “height” parameter). And mainly because all the gameplay takes place in the ground’s 2D plane anyway so all objects are guaranteed to have a root object that has the ground position. In your own game, it might be easier to just use the first option.

[ExecuteInEditMode]
[RequireComponent(typeof(Renderer))]
public class IsometricObject : MonoBehaviour
{
   private const int IsometricRangePerYUnit = 100;
   
   [Tooltip("Will use this object to compute z-order")]
    public Transform Target;
    
    [Tooltip("Use this to offset the object slightly in front or behind the Target object")]
    public int TargetOffset = 0;
    
    void Update()
    {
        if (Target == null)
            Target = transform;
        Renderer renderer = GetComponent();
        renderer.sortingOrder = -(int)(Target.position.y * IsometricRangePerYUnit) + TargetOffset;
    }
}

This is how this example is set up in Unity:

The birdhouse references the tree for its depth.

 

And this is how it behaves in practice:

 

Ground Projection

For certain visual elements and effect, we wanted them to look properly projected on the ground, but also not spend too much time on making art for them. The ‘isometric’ view of the game means that anything that is horizontally on the ground should look squashed vertically.
For simple sprites, this is quite easy. Just draw them directly with the correct perspective and place them in the game.

Things get more complicated when you need something that should be able to rotate in any direction. Like something to show the direction the character is moving in, or some visual effect sweeping the ground towards your attacking direction. Especially if these are things that are animated, drawing them manually for all possible orientations is out of the question (or so the artists claim).

Our solution is: the artists draw and animate these effects as if viewed top-down, and the programmers take care of transforming them at runtime to look as if they were projected on the ground. Without any transformation, just taken from the artists and placed in the game rotating them to match the player’s direction they look like below.

 

We need to squash them vertically. For a sprite that doesn’t rotate, just scaling on the Y dimension does the job. But for a rotating sprite this doesn’t work, and it’s even worse for animations. The first thing we tried was a custom shader that transformed the vertices in the local space to squash them vertically (naturally, we went with the most complex solution first), but this needed to break batching to work properly with all sprites and animations. Or I was just bad at writing that shader, maybe…

The final solution is absurdly simple. Just rotate the object around the X axis, and it works!
However, we also wanted to:

  • apply the rotation automatically and consistently, and not have to remember or care about setting the X component of the rotation ourselves
  • be able to set the Z component of the rotation (to make the effect rotate towards any game world direction)
  • not have to visit all ‘ground projected’ effects when changing the amount of squashing

Basically, the game should not have to know that a rotation on X axis is happening. If an object has the ProjectOnGround behavior attached, it should just draw properly without additional effort. So we do the math just before rendering, and restore the rotation to its normal value right after. This hides the rotation around the X axis from the rest of the code.

[ExecuteInEditMode]
    public class ProjectOnGround : MonoBehaviour
    {
        private Quaternion savedRotation;

        // called before rendering the object        
        void OnWillRenderObject()
        {
            savedRotation = transform.rotation;
            var eulers = transform.rotation.eulerAngles;
            transform.rotation = Quaternion.Euler(Constants.Isometric.PerspectiveAngle, eulers.y, eulers.z);
        }

        //called right after rendering the object
        void OnRenderObject()
        {
            transform.rotation = savedRotation;
        }
    }

Simple and easy. Too bad I wasted time trying to write a shader for this. The result looks good and we can simple ‘project’ any object by just adding this behavior to it.

 

 

 

[출처] https://breadcrumbsinteractive.com/two-unity-tricks-isometric-games/

 

Two Unity tricks for isometric games - Breadcrumbs

Here are two small tricks that can help if you’re making an isometric 2D game in Unity. Ok, so not actually isometric, but that’s the term we’re used to in videogames, so we’ll go with it. These are quite basic and if you’re working on such a gam

breadcrumbsinteractive.com

 

반응형
Posted by blueasa
, |

Link : http://forum.unity3d.com/threads/unity-4-5-new-hierarchy-window-sorting.248298/#post-1642742


[File]


$AlphaNumericSort.cs





기존의 이름이 아닌 트랜스폼 기준으로 변경되었는데요.


(전 처음에 4.5 버전 버그인줄 알고 당황-_-;)



링크의 글 중간에 보시면

$AlphaNumericsort.cs

파일을 다운 받으시고

프로젝트 폴더/Assets/Editor/ 

에 넣어주세요.

유니티를 다시 띄우면 그림처럼 아이콘이 하나가 추가됩니다.

이 아이콘을 누르시면 소팅 방식을 트랜스폼 혹은 이름으로 변경 가능해집니다.




출처 : http://www.gamecodi.com/board/zboard.php?id=GAMECODI_Talkdev&page=1&sn1=&divpage=1&sn=on&ss=on&sc=on&keyword=sort&select_arrange=headnum&desc=asc&no=2703

반응형

'Unity3D > Tips' 카테고리의 다른 글

Scene뷰에서 Handles.Label()  (0) 2015.05.08
[링크] 유니티5 업그레이드 가이드  (0) 2015.03.30
BBCode tags reference  (0) 2015.02.08
안드로이드 유니티 리모트 4 연동 문제 해결하기  (0) 2015.02.04
Unity Platform Defines  (0) 2015.01.28
Posted by blueasa
, |

Sorting Arrays

Programming/C# / 2014. 11. 21. 11:53

Sorting Arrays [C#]

This example shows how to sort arrays in C#. Array can be sorted using static method Array.Sortwhich internally use Quicksort algorithm.

Sorting array of primitive types

To sort array of primitive types such as intdouble or string use method Array.Sort(Array) with the array as a paramater. The primitive types implements interface IComparable, which is internally used by the Sort method (it calls IComparable.Com­pareTo method). See example how to sort int array:

[C#]

// sort int array
int[] intArray = new int[5] { 8, 10, 2, 6, 3 };
Array.Sort(intArray);
// write array
foreach (int i in intArray) Console.Write(i + " ");  // output: 2 3 6 8 10

or how to sort string array:

[C#]

// sort string array
string[] stringArray = new string[5] { "X", "B", "Z", "Y", "A" };
Array.Sort(stringArray);
// write array
foreach (string str in stringArray) Console.Write(str + " "); // output: A B X Y Z

Sorting array of custom type using delegate

To sort your own types or to sort by more sophisticated rules, you can use delegate to anonymous method. The generic delegate Comparison<T> is declared as public delegate int Comparison<T> (T x, T y). It points to a method that compares two objects of the same type. It should return less then 0 when X < Y, zero when X = Y and greater then 0 when X > Y. The method (to which the delegate points) can be also an anonymous method (written inline).

Following example demonstrates how to sort an array of custom type using the delegate to anonynous comparison method. The custom type in this case is a class User with properties Name and Age.

[C#]

// array of custom type
User[] users = new User[3] { new User("Betty", 23),  // name, age
                             new User("Susan", 20),
                             new User("Lisa", 25) };

[C#]

// sort array by name
Array.Sort(users, delegate(User user1, User user2) {
                    return user1.Name.CompareTo(user2.Name);
                  });
// write array (output: Betty23 Lisa25 Susan20)
foreach (User user in users) Console.Write(user.Name + user.Age + " ");

[C#]

// sort array by age
Array.Sort(users, delegate(User user1, User user2) {
                    return user1.Age.CompareTo(user2.Age); // (user1.Age - user2.Age)
                  });
// write array (output: Susan20 Betty23 Lisa25)
foreach (User user in users) Console.Write(user.Name + user.Age + " ");

Sorting array using IComparable

If you implement IComparable interface in your custom type, you can sort array easily like in the case of primitive types. The Sort method calls internally IComparable.Com­pareTo method.

[C#]

// custom type
public class User : IComparable
{
  // ...

  // implement IComparable interface
  public int CompareTo(object obj)
  {
    if (obj is User) {
      return this.Name.CompareTo((obj as User).Name);  // compare user names
    }
    throw new ArgumentException("Object is not a User");
  }
}

Use it as you sorted the primitive types in the previous examples.

[C#]

// sort using IComparable implemented by User class
Array.Sort(users);  // sort array of User objects



출처 : http://www.csharp-examples.net/sort-array/

반응형
Posted by blueasa
, |
List<cTag> week = new List<cTag>();
// add some stuff to the list
// now sort
week.Sort(delegate(cTag c1, cTag c2) { return c1.date.CompareTo(c2.age); });



참조 : http://stackoverflow.com/questions/3163922/sort-a-custom-class-listt

반응형
Posted by blueasa
, |