카테고리 없음

0602 C#(인터페이스, 추상클래스) , 유니티(체력 UI)

버스창문 2025. 6. 2. 17:59
interface ILogger // 메서드나 속성, 이벤트 등을 정의 해두는 곳
                  // 구현은 여기서 못함
{
    void WriteLog(string message);
}
class ConsoleLogger : ILogger
{
    public void WriteLog(string message) // 구현하지 않으면 에러가 남(구현을 강제함)
    {
        Console.WriteLine($"{DateTime.Now.ToLocalTime},{message}"); 
    }
}

콘솔에 로그 띄우기

class FileLogger : ILogger 
{
    private StreamWriter _writer;
    public FileLogger(string path)
    {
        _writer = File.CreateText(path); // 파일을 생성하고 스트림 라이터를 초기화
        _writer.AutoFlush = true; // 자동으로 버퍼를 비우도록 설정
    }
    public void WriteLog(string message)
    {
        _writer.WriteLine($"File log : {DateTime.Now.ToLocalTime} , {message}");
    }
}

파일을 생성해서 로그띄우기

class ClimateMonitor
{
    private ILogger logger;
    public ClimateMonitor(ILogger logger)
    {
        this.logger = logger;
    }
    public void Start()
    {
        while (true)
        {
            Console.Write("온도 입력 : ");
            string temperInput = Console.ReadLine();
            if (temperInput == "")
            {
                break;
            }
            logger.WriteLog($"현재 온도 : {temperInput}");
        }
    }
}

//Ilogger 형식의 클래스를 생성자에서 입력받도록

ILogger logger = new ILogger(); // 그냥 생 Ilogger 이용하려고 시도할시 에러남
ClimateMonitor monitor = new ClimateMonitor(logger);

 

 

인터페이스가 인터페이스를 상속받을수도 있다.

클래스나 구조체도 상속받을 수 있다.

 

//인터페이스를 상속하는 인터페이스의 예시

interface ILogger2
{
    void WriteLog(string message);
}
interface IFormattableLogger : ILogger2
{
    void WriteLog(string message, params Object[] args);
}
interface ILogger2
{
    void WriteLog(string message);
}
interface IFormattableLogger : ILogger2
{
    void WriteLog(string message, params Object[] args);
}
class ConsoleLogger2 : IFormattableLogger
{
    public void WriteLog(string message) // Ilogger2에 있는거
    {

    }
    public void WriteLog(string message, params object[] args) // formmattable에 있는거
    {

    }
}

두개 다 구현해야 에러가 안남
ConsoleLogger2 logger = new ConsoleLogger2();
logger.WriteLog("123");
logger.WriteLog("{0} , {1} , {2} , {3}", 1, "5", 2+3, 7.0);

 

    interface IRunnable
    {
        void Run();
    }
    interface IWalkable
    {
        void Walk();
    }
    class Human : IWalkable, IRunnable
    {
        public void Walk() { }
        public void Run() { }
    }

인터페이스는 다중상속이 가능하다.

위에 2개는 내용구현 안해서 아래거는 클래스 다중 상속 시도해서

인터페이스는 다중상속해도 에러가 나지 않는다.

 

 

______________________________________________________________________

 

추상 클래스

추상 클래스는 인터페이스와 달리 구현도 포함할 수 있다.

다만 추상클래스는 인스턴스를 생성(new ~~()) 할 수 없다.

자식 클래스에서 상속받아 인스턴스를 생성한다.

public abstract class AbstractBase
{
    protected void PrivateMethodA()
    {
        Console.WriteLine("A called");
    }
    public void PublicMethodA()
    {
        Console.WriteLine("Public A called");
    }
    public abstract void AbstractMethodA(); // 추상 메서드는 구현부가 없음,구현하려하면 에러남
                                            // 추상 메서드 하나라도 포함 시 클래스도 추상 클래스 여야함

}

class Derived : AbstractBase
{
    public override void AbstractMethodA()
    {
        Console.WriteLine("Derived Abstract A called");
    }
}

추상 클래스를 그대로 쓰려하니 에러나는 모습

위에서 protected로 되어있던걸 쓰려하니 에러나는 모습

 

 

______________________________________________________________________

 

HPUI

적 위에 띄우고

깎이면 색 점점 바뀌고 (초 -> 노 -> 빨)

UI는 메인카메라를 바라보도록

 

 

 

몬스터 내에 UI-Canvas생성

 

 

world space로 바꾸고 위치 세부조정

 

Panel생성

panel에 이미지 생성

panel에 text생성

 

public class LookAtCamera : MonoBehaviour
{
    public Transform canvasTr;
    public Transform cameraTr;


    void Start()
    {
        canvasTr = this.transform;
        cameraTr = Camera.main.transform;
    }
    void Update()
    {
        canvasTr.LookAt(cameraTr); //캔버스가 카메라를 바라봄
    }
}

코드 작성후 캔버스에 추가

 

 

 

+

만약 글이 뒤집어진 상태일 경우

 

text쪽에서 회전 가능

 

___________________________________________________________________

 

플레이어 체력 UI

그냥  UI만들던데로 만듬

 

안티엘리어싱 방지용

 

_________________________________________________________

조준점

void Update()
{
    ray = new Ray(this.transform.position, this.transform.forward); // 앞으로 레이 발사
    //Debug.DrawRay(this.transform.position, this.transform.forward * 100 , Color.red);
    if(Physics.Raycast(this.ray, out hit, 20f , 1 << 6)) //6번 레이어에 닿으면
    {
        Debug.DrawRay(this.transform.position, this.transform.forward * 100 , Color.red);
        Debug.Log(hit.rigidbody.gameObject.name);

    }
}

보고있으면 debug가 작동하도록

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

public class CrossHair : MonoBehaviour
{
    private float startTime = 0;
    private float duration = 0.3f;
    public float minSize = 0.7f;
    public float maxSize = 1.2f;
    private Color originColor = Color.white;
    private Color gazeColor = Color.red;
    private Image crossHairImage;
    public bool isGaze = false;
    void Start()
    {
        startTime = Time.time;
        this.transform.localScale = Vector3.one * minSize;
        this.crossHairImage = GetComponent<Image>();
        this.crossHairImage.color = originColor;
    }

    void Update()
    {
        if (isGaze) 
        {
            float t = (Time.time - startTime) / duration;
            Debug.Log(t);
            this.transform.localScale = Vector3.one * Mathf.Lerp(minSize, maxSize, t);
            this.crossHairImage.color = gazeColor;
        }
        else
        {
            this.startTime = Time.time;
            this.transform.localScale = Vector3.one * minSize;
            this.crossHairImage.color = originColor;
        }
    }
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class EyeCast : MonoBehaviour
{
    Ray ray;
    RaycastHit hit;
    public CrossHair crossHair;

    void Start()
    {
        
    }
    void Update()
    {
        ray = new Ray(this.transform.position, this.transform.forward); // 앞으로 레이 발사
        //Debug.DrawRay(this.transform.position, this.transform.forward * 100 , Color.red);
        if (Physics.Raycast(this.ray, out hit, 20f, 1 << 6))
        {
            Debug.DrawRay(this.transform.position, this.transform.forward * 100, Color.red);
            //Debug.Log(hit.rigidbody.gameObject.name);
            this.crossHair.isGaze = true;
        }
        else
        {
            this.crossHair.isGaze = false;
        }
    }
}