250102

lililllilillll·2025년 1월 2일

개발 일지

목록 보기
39/350

✅ 오늘 한 일


  • C# 교과서 읽기
  • Particle System 공부


📝 배운 것들


🏷️ Unity :: Particle System

https://www.youtube.com/watch?v=2De-Bp262eE

Particle System parameters

  • Prewarm : 미리 뿌려져 있는거. Looping 체크 돼있으면 활성화됨. 켜져 있으면 Start Delay 비활성화됨.
  • Start Delay : 처음 시작할 때 딜레이
  • Start Lifetime : 방출된 입자가 얼마 동안 살아있느냐
    • 우측 화살표 옵션에 Random Between Two Constants로 랜덤한 Lifetime 설정 가능
    • Curve 고르면 시간에 따라 Lifetime 조절 가능
    • Curve 골랐는데 아무것도 안 뜨면 Inspector 맨 아래에서 Particle System Curves 위로 올리기
    • Random Between Two Curve : 두 Curve 사이에서 랜덤한 값 적용
    • 모든 파라미터에서 이런 옵션 설정 가능
  • Start Speed : 방출되는 속도
  • 3D Start Size : xyz축 크기 따로 조절 가능
  • Start Size : 방출되는 물체의 크기
  • Start Rotation : 회전돼있는 각도
  • Flip Rotation : 반대로 돌려주는 값. 1이면 완전히 반대로 돌아감. (보통 Start Rotation을 그냥 쓴다)
  • Start Color : 방출되는 물체의 색깔
    • Gradient : 시간에 따라 방출되는 색을 점점 변화시키고 싶을 때 사용
    • Random Color : Mode는 Blend, Fixed를 고를 수 있다.
    • 색상 바 아래를 클릭하면 화살표가 새로 만들어지고, 색 지정 가능. 화살표 떼어놓으면 삭제됨.
  • Gravity Modifier : 값을 주면 아래로 떨어짐. 음수가 되면 역중력.
  • Simulation Space : 파티클의 위치 기준
    • Local : 파티클 시스템 움직이면 붙어서 같이 따라다님
    • World : 파티클 시스템 움직여도 안 따라감
    • Custom : 다른 오브젝트 기준으로 따라다니게 할 수 있다
  • Simulation Speed : 파티클 시스템 속도를 전체적으로 관장하는 값
  • Delta Time : Unscaled로 설정하면 일시정지해도 파티클 움직임 (보통 Scale로 두고 안 건든다)
  • Scailing Mode
    • Hierarchy : 부모 오브젝트 크기 건드리면 파티클 크기도 같이 조절됨
    • Local : 파티클 시스템 자체 transform 크기 조절하면 파티클 크기도 같이 조절됨
    • Shape : 파티클 크기는 안 변하고 파티클 시스템의 범위만 늘어남
  • Max Particles : 화면에 보여지는 최대 파티클 개수
  • Auto Random Seed : 난수 시드 지정 자동으로 할건지 직접 정할건지
  • Stop Action : 파티클이 멈췄을 때 파티클을 어떻게 처리할거냐 (Disable, Destroy, Callback)
  • Culling Mode : 카메라가 파티클 안 비추고 있을 때 파티클을 어떻게 처리할거냐

Emission

방출되는 파티클의 개수를 제어한다

  • Rate over Time : Duration 1초에 Rate ove Time 10을 설정하면 총 9개가 방출된다
  • Rate over Distance : 움직일 때마다 몇개가 나오게 할건지 (Rate over Time과는 별개인듯)
  • Bursts : 한 번에 여러 개가 나오게 하고 싶을 때 사용. 리스트에 더 추가해서 여러 개의 Burst 만들 수 있다.
    • (TroubleShooting) Start Lifetime을 첫 시작점이 0에 가까운 Curve로 해놨더니 나오자마자 바로 사라졌었음. Constant로 바꿔서 해결.
    • (TroubleShooting) 2D에서 원 모양으로 한 번에 랜덤하게 나오게 하고 싶었는데 반원 형태로만 나옴
      • x축 Rotation을 0으로 바꾸고, Shape를 Circle로 바꾸고, Loop를 Burst Spread로 바꿔서 해결.

Shape

파티클이 방출되는 모양 설정 (Cone 기준 설명)

  • Shape
    • Mesh : Mesh 모양에 맞춰서 방출. fbx 파일에서 데이터를 받아온다.
    • Mesh Renderer, Skinned Mesh Renderer : 캐릭터 프리팹에서 데이터 받아온다. 캐릭터에 불 붙일 때 사용.
    • Sprite : Sprite 이미지에 맞춰서 방출.
    • Sprite Renderer : Mesh ↔ Mesh Renderer, Sprite ↔ Sprite Renderer 둘의 관계는 같다
  • Angle : cone 너비
  • Radius : 기둥 밑면 넓이
  • Radius Thickness : 면에 딱 붙어서 생성될건지
  • Arc : 각도 얼마만큼만의 면적까지만 쓰고 싶은지
    • Mode
      • Loop : 차례대로 위치 바꿔가며 방출
      • Ping-Pong : 한 번 돌았다가 다시 회귀함
      • Burst Spread : Bursts와 함께 사용하여 균등하게 방출
    • Spread : 간격을 얼만큼 띄워서 생성할건지
    • Speed : 위치를 얼마나 빠르게 바꿀 건지
  • Length : 원뿔 높이
  • Emit from
    • Base : 원뿔 밑면에서만 생성됨
    • Volume : 원뿔 안에서 생성됨
  • Texture : 텍스처 안의 랜덤 색깔 골라서 방출 (특정 물체 색깔하고 똑같이 맞출 때 사용)
  • Position, Rotation, Scale : Particle System의 transform을 변경하면 파티클도 같이 변하니까 대신 이거 변경하면 됨
  • Align To Diretion : 방출 방향으로 날아감
  • Randomize Direction : 파티클 방출 방향 랜덤화
  • Spherize Direction : 방출 방향이 원뿔 모양을 얼마나 따라갈건지
  • Randomize Position : 파티클 방출 위치 랜덤화

Velocity over Lifetime

추가 속도 부여

  • Linear : 축마다 상수 속력 추가
  • Space : 뭘 기준으로 속도를 추가할건지
  • Orbital : 기둥을 따라 돈다 (소용돌이 만들 때 사용)
  • Offset : 기둥 축 위치 조절
  • Radial : 올라가면서 반경이 점점 넓어짐
  • Speed Modifier : 회전 속도가 빨라짐

Limit Velocity over Lifetime

시간에 따라 속도 줄이기

  • Seperate Axes : 축마다 지정 (보통 끔)
  • Speed : Curve로 둔 후에
  • Dampen : 1로 주기
  • Drag : 더 땡김

Inherit Velocity

뭔가가 움직였다면 파티클 속도도 영향 받음
(Simulation Space가 World일 때만 작동)

Force over Lifetime

Velocity over Lifetime과 비슷하지만
가속도를 기반으로 좀 더 자연스럽게 속도 증가

Color by Lifetime

시간에 따라 색상 변화

Color by Speed

파티클 속력에 따라 색상 변화

Size over Lifetime

시간에 따라 크기 변화

Size by Speed

파티클 속력에 따라 크기 변화

Rotation over Lifetime

시간에 따라 회전 변화

Rotation by Speed

파티클 속력에 따라 회전 변화
(굴러떨어지다 멈추는 것들을 파티클로 구현할 때 사용)

External Forces

바람같은 외부 힘에 얼마나 영향 받을지

Noise

노이즈 맵 따라 불규칙하게 이동

Collision

벽 뚫고가지 않게 충돌 설정
(모바일에선 성능 이슈 있긴 함)

Trigger

특정 영역에 들어갔을 때 파티클이 어떤 짓을 할건지

Sub Emitters

파티클이 꺼지거나 없어질 때 또 다른 파티클 생성 (폭죽 만들 때 사용)

Texture Sheet Animation

Sprite Texture를 파티클에서 순서대로 사용할 때
Material의 Base Map에 Sprite 넣고 Particle System에 적용하면 된다

Lights

파티클 마다 Light 박는거.
실무에서 안 쓴다. 성능 이슈 있음.

Trails

파티클이 궤적을 남긴다

  • Texture Mode : Stretch는 sprite 늘려서, Tile은 sprite 연결해서 나옴

Custom Data

파티클에서 셰이더 제어

Renderer

  • Render Mode
    • Billboard : 카메라를 돌려도 파티클 방향은 카메라를 바라봄
  • Sort Mode : 뭘 앞에 보여줄 건지. 근데 보통 None으로 둠.
  • Sorting Fudge : 같은 파티클 시스템 안의 파티클 간의 순서 지정
  • Max Particle Size : 카메라가 가까이 갈 때 파티클이 얼마나 커질지
  • Render Alignment : 파티클이 바라보는 방향
    • View : 카메라 방향
    • World : 월드 축 기준
    • Local : 로컬 축 기준
    • Facing : 카메라 게임 오브젝트 방향 (그냥 View 쓴다)
  • Masking : (Sprite Mask 컴포넌트 부착된) 부모 게임 오브젝트 기준으로 마스킹 (모니터 화면 안에서 번개가 친다던가 할 때 사용)
  • Order in Layer : 파티클 시스템 전체의 순서 지정


📖 C# 교과서


46 특성과 리플렉션

46.1 특성

특성은 코드에 설명을 추가로 붙이는 것이다.

[Obsolete]
public class OldClass {}

46.2 Obsolete 특성 사용하기

46.4 [Conditional] 특성 사용하기

특정 기호에 따라 실행 여부를 결정할 수 있다.

#define RELEASE
using System;
using System.Diagnostics;

public class ConditionalDemo
{
    static void Main()
    {
        DebugMethod();
        ReleaseMethod();
    }

    [Conditional("DEBUG")]
    static void DebugMethod() => Console.WriteLine("디버그 환경에서만 표시");

    [Conditional("RELEASE")]
    static void ReleaseMethod() => Console.WriteLine("릴리스 환경에서만 표시");
}

비주얼 스튜디오 상단에 있는 드롭다운에서 프로그램에 debug와 release 기호를 제공할 수 있다.

46.5 특성을 사용하여 메서드 호출 정보 얻기

using System.Runtime.CompilerServices;
using static System.Console;

class CallerInformation
{
    static void Main()
    {
        TraceMessage("여기에서 무엇인가 실행...");
    }

    public static void TraceMessage(string message,
        [CallerMemberName] string memberName = "",
        [CallerFilePath] string sourceFilePath = "",
        [CallerLineNumber] int sourceLineNumber = 0)
    {
        WriteLine("실행 내용 : " + message);
        WriteLine("멤버 이름 : " + memberName);
        WriteLine("실행 내용 : " + sourceFilePath);
        WriteLine("실행 내용 : " + sourceLineNumber);
    }
}

실행 내용 : 여기에서 무엇인가 실행...
멤버 이름 : Main
실행 내용 : C:\Users...\Project1\ConsoleApp1\Program.cs
실행 내용 : 8

46.6 사용자 지정 특성 만들기

using System;

public class SampleAttribute : Attribute
{
    public SampleAttribute() => Console.WriteLine("사용자 지정 특성 사용됨");
}

[Sample] public class CustomAttributeTest { }

class AttributePractice
{
    static void Main()
    {
        Attribute.GetCustomAttributes(typeof(CustomAttributeTest));
    }
}

특성을 사용할 때는 다음 두 가지 방식이 모두 가능합니다:
[Sample] // 접미사 Attribute 생략
[SampleAttribute] // 완전한 이름 사용

매개변수가 있는 사용자 지정 특성 만들기

[AttributeUsage(AttributeTargets.Method | AttributeTargets.Class, AllowMultiple = true)]
public class NickNameAttribute : Attribute
{
	public string Name { get; set; }
    public NickNameAttribute(string name) { Name = name; }
}

46.7 리플렉션

reflection : 동적으로 특정 어셈블리 또는 형식에 대한 메타데이터를 Type 개체로 반환하는 것

46.8 Type과 Assembly 클래스

> string r = "Reflection";
> Type t = r.GetType();
> t

Type 클래스로 문자열 개체 정보를 얻어 출력하는 리플렉션 예제

> System.Reflection.Assembly assembly = typeof(System.Random).Assembly;
> assembly
[System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85dea779]

Aseembly 클래스를 사용하여 특정 어셈블리의 정보를 얻는 예제

46.9 특정 클래스의 메서드와 속성을 동적으로 호출하기

// Test 클래스에 대한 Type 개체 가져오기
Type t = typeof(test);

// 원하는 멤버를 조건에 따라 가져오기
MemberInfo[] members = t.GetMembers(BindingFlags.Static | BindingFlags.Public);

리플렉션을 사용하여 Test 클래스의 정적 멤버 리스트를 얻는 예제

47 객체와 객체 지향 프로그래밍 (OOP)

47.1 객체 지향 프로그래밍 소개하기

개체

클래스를 사용하여 새로운 형식을 정의하고,
개체는 데이터와 기능을 숨기는 캡슐화 기능을 제공한다.

  • (is something) 무엇이 된다.
  • (has data) 데이터를 가진다.
  • (perfoms action) 기능을 수행한다.

클래스 : 설계도
객체 : 설계도로 조립한 물건
필드 : 클래스의 부품. 외부에 공개할 땐 public 대신 readonly와 const 필드만 허용하길 권장
생성자 : 자동차 시동 걸기. 클래스 내 필드를 초기화한다.
소멸자 : 자동차 시동 끄기. GC 엔진이 대신 해준다.
메서드 : 클래스의 기능과 동작.
속성 : 자동차의 속성, 특징, 색상, 모양 등 표현. private, public
인덱서 : 자동체 카탈로그 역할. 만든 객체를 배열 형식으로 사용할 수 있게 한다.

47.4 캡슐화를 사용하여 좀 더 세련된 프로그램 만들기

public class Person
{
	private string name;
    public void SetName(string n) => name = n;
    public string GetName() => this.name;
}

47.5 다형성 기법을 사용하여 프로그램 융통성 높이기

public abstract class Animal
{
	public abstract string Cry();
}
public class Dog : Animal
{
	public override string Cry() => "멍멍멍";
}
public class Cat : Animal
{
	public override string Cry() => "야옹";
}
public class Trainer
{
	public void DoCry(Animal animal)
    {
    	Console.WriteLine("{0}", animal.Cry());
    }
}

47.6 클래스의 멤버 종합 연습: 자동차 클래스 구현하기

using System;
using System.Collections;

// 네임스페이스 : 클래스 이름 충돌 방지
namespace CarWorld
{
    // 인터페이스 : 표준, 다중 상속
    interface IStandard { void Run(); }

    /// <summary>
    /// 클래스: 설계도
    /// </summary>
    class Car : IStandard
    {
        #region 필드
        private string name;
        private string[] names;
        private readonly int _Length;
        #endregion

        #region 생성자
        public Car()
        {
            this.name = "좋은차";
        }
        public Car(string name)
        {
            this.name = name;
        }
        public Car(int length)
        {
            this.name = "좋은차";
            _Length = length;
            names = new string[length];
        }
        #endregion

        #region 메서드
        public void Run() => Console.WriteLine("{0} 자동차가 달립니다.", name);
        #endregion

        #region 속성
        public string Name
        {
            get { return name; }
            set { name = value; }
        }
        public int Length { get { return _Length; } }
        #endregion

        #region 소멸자
        ~Car()
        {
            Console.WriteLine("{0} 자동차가 폐차됨.", name);
        }
        #endregion

        #region 인덱서
        public string this[int index]
        {
            get { return names[index]; }
            set { names[index] = value; }
        }
        #endregion

        #region 이터레이터
        public IEnumerator GetEnumerator()
        {
            for (int i = 0; i < _Length; i++)
            {
                yield return names[i];
            }
        }
        #endregion

        #region 대리자
        public delegate void EventHandler();
        #endregion

        #region 이벤트
        public event EventHandler Click;
        #endregion

        #region 이벤트 처리기
        public void OnClick()
        {
            if (Click != null)
            {
                Click();
            }
        }
        #endregion
    }

    class CarWorld
    {
        static void Main()
        {
            Car campingCar = new Car("캠핑카");
            campingCar.Run();

            Car sportsCar = new Car();
            sportsCar.Name = "스포츠카";
            sportsCar.Run();

            Car cars = new Car(2);
            cars[0] = "1번 자동차";
            cars[1] = "2번 자동차";
            for (int i = 0; i < cars.Length; i++)
            {
                Console.WriteLine(cars[i]);
            }

            foreach (string name in cars)
            {
                Console.WriteLine(name);
            }

            Car btn = new Car("전기자동차");
            btn.Click += new Car.EventHandler(btn.Run);
            btn.Click += new Car.EventHandler(btn.Run);
            btn.OnClick();
        }
    }
}


profile
너 정말 **핵심**을 찔렀어

0개의 댓글