새 프로젝트는 .Net Framework로 만드는데 없으면


Visual Studio Installer에서 수정을 누르고 


.Net 데스크 톱 선택 후 설치하면 생성됨

Tab : 오른쪽 들여쓰기(4개의 공백문자로 치환)


Shift + Tab : 왼쪽 들여쓰기

메서드 : 일련의 문을 포함하는 코드 블록

메인 메서드 : 프로그램이 시작되면 실행이 되는 첫번째 메서드(프로그램 제어가 시작되고 끝나는 곳)

프로그램 생성 시 자동 완성되고 지우면 안된다

Main을 main으로 바꾸면 안된다.

코드 작성시 에러가 나면 Main메서드를 지웠거나 수정했을 수 있다

'Study > C#' 카테고리의 다른 글

[C#] 오류와 디버깅  (0) 2024.05.24
[C#] 컴파일과 빌드  (0) 2024.05.24
[C#] 주석  (0) 2024.05.24
[C#] 데이터 타입 bool, char, object  (0) 2024.05.24
[C#] 변수와 값, 데이터 타입 (int, float, string)  (0) 2024.05.23

테이블을 SQL문을 활용해서 만들 수 있다.

 

CREATE TABLE indexTBL (first_name varchar(14), last_name varchar(16), hire_date date);

INSERT INTO indexTBL
SELECT first_name, last_name, hire_date
FROM employees.employees
LIMIT 500;

SELECT * FROM indexTBL;

 

 

 

아래 모양 키를 누른후 Execution Plan 클릭

 

 

 

Execution Plan이란?

 

그 후

 

 CREATE INDEX idx_indexTBL_firstname ON indexTBL(first_name);

 

 

 

 

뷰란?

가상의 테이블

원래 있는 테이블을 가상으로 만들어서 뷰테이블?이라고 만든 후 SELECT로 볼 수 있다.

 

뷰는 수정을 할 수 있지만 SELECT만 권장

 

CREATE VIEW uv_memberTBL
AS
SELECT memberName, memberAddress FROM uv_membertblmemberTBL;

 

 

 

 

 

DELIMITER 는 '구분 문자'를 의미한다.

뒤에 //가 나오면 기존의 세미클론(;)을 // 로 대신한다는 것이다.

 

 

프로시저란?

 

 

SELECT를 한다면 어떻게 탐색해서 들어갔는지 보여주는 과정

 

 

 

 

프로시저 만들기

 

1. 델리미터를 작성 후 실행

 

2. CREATE로 만들고

3. BEGIN과 END로 실행

 

4. 셀렉트 문을 실행

 

즉, 총 3 번을 실행해야 한다.

 

그러면 이렇게 프로시져가 만들어짐을 확인할 수 있다.

 

 

트리거란?

 

테이블에 부착되어 테이블에 INSERT나 UPDATE 또는 DELETE 작업이 발생되면 실행되는 코드

 

 

가끔 업데이트할때 오류가 나는 이유는 맨 아래 세이프 모드가 체크 되어있기 때문에

테스트를 하려면 풀어주면 된다.

 

가끔 업데이트가 안될 경우 Reconnect

 

 

생성 후 잘 지워 지는 것을 확인 할 수 있다.

 

 

이제 지워진 것을 확인할 테이블을 만들 것이다.

CREATE TABLE deletedMemberTBL(
	memberID CHAR(8),
    memberName CHAR(5),
    memberAddress CHAR(20),
    deletedDate DATE
);

 

 

CREATE VIEW uv_membertbl
AS SELECT memberName, memberAddress FROM memberTBL;

DELIMITER //
CREATE PROCEDURE myProc()
BEGIN
    SELECT * FROM memberTBL WHERE memberName = '당탕이';
    SELECT * FROM productTBL WHERE productName = '냉장고';
END //
DELIMITER ;

INSERT INTO memberTBL VALUES ('Figure', '연아', '경기도 군포시 당정동');
UPDATE memberTBL SET memberAddress = '서울 강남구 역삼동'
WHERE memberName = '연아';

DELETE FROM memberTBL WHERE memberName = '연아';
SELECT * from memberTBL;

CREATE TABLE deletedMemberTBL(
	memberID CHAR(8),
    memberName CHAR(5),
    memberAddress CHAR(20),
    deletedDate DATE
);

DELIMITER //
CREATE TRIGGER trg_deletedMemberTBL
	AFTER DELETE
	ON memberTBL
	FOR EACH ROW
BEGIN
	INSERT INTO deletedmembertbl
		VALUES (OLD.memberID, OLD.memberName, OLD.memberAddress, CURDATE());
END //

DELIMITER ;

 

당탕이라는 멤버를 지우고 지워지는지 확인

 

 

백업하는 법

 

C에 DB백업이라는 폴더 생성

왼쪽에 아래에 Administration 클릭후 Data Export

 

모두 체크 후 -> Star Export

 

추출이 잘 되어있음을 확인 할 수 있다.

 

이제 데이터를 옮길 것이다.

 

삭제가 되거나 문제가 생길 경우 Import 해서 저장된 데이터를 가져올 수 있다.

 

 

 

 

 

'산대특' 카테고리의 다른 글

[애드몹] 배너 광고 붙이기  (0) 2024.06.28
플레이콘솔 리더보드에 점수 올리기  (0) 2024.06.26
2D 3Matchpuzzle - 블록 위치 찾기 테스트  (0) 2024.05.16
2D 3Matchpuzzle - 빈공간 찾기  (0) 2024.05.14
Download Python  (0) 2024.05.08

https://github.com/wlgys8/Sprites-Outline

 

GitHub - wlgys8/Sprites-Outline: Outline effect for Unity SpriteRenderer

Outline effect for Unity SpriteRenderer. Contribute to wlgys8/Sprites-Outline development by creating an account on GitHub.

github.com

 

'라이브러리' 카테고리의 다른 글

DOTween  (1) 2024.03.29

완전 탐색을 하여 2중 for문을 돌린다

 

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

public class MatchTest : MonoBehaviour
{
    private static readonly int Rows = 4;
    private static readonly int Cols = 4;
    
    private int[,] board =
    {
        {1, 1, 2, 0},
        {1, 1, 1, 1},
        {2, 1, 0, 1},
        {0, 0, 1, 1}
    };
    void Start()
    {
        FindMatchingBlocks();
    }
    
    private void FindMatchingBlocks()
    {
        HashSet<(int, int)> matchedBlocks = new HashSet<(int, int)>();

        for (int i = 0; i < Rows; i++)
        {
            for (int j = 0; j < Cols; j++)
            {
                CheckHorizontalMatch(i, j, matchedBlocks);
                CheckVerticalMatch(i, j, matchedBlocks);
            }
        }

        Debug.Log("Matching Blocks:");
        foreach (var block in matchedBlocks)
        {
            Debug.Log($"({block.Item1}, {block.Item2})");
        }
    }

    private void CheckHorizontalMatch(int row, int col, HashSet<(int, int)> matchedBlocks)
    {
        if (col + 2 < Cols &&
            board[row, col] == board[row, col + 1] &&
            board[row, col] == board[row, col + 2])
        {
            matchedBlocks.Add((row, col));
            matchedBlocks.Add((row, col + 1));
            matchedBlocks.Add((row, col + 2));
        }
    }

    private void CheckVerticalMatch(int row, int col, HashSet<(int, int)> matchedBlocks)
    {
        if (row + 2 < Rows &&
            board[row, col] == board[row + 1, col] &&
            board[row, col] == board[row + 2, col])
        {
            matchedBlocks.Add((row, col));
            matchedBlocks.Add((row + 1, col));
            matchedBlocks.Add((row + 2, col));
        }
    }
}

'산대특' 카테고리의 다른 글

플레이콘솔 리더보드에 점수 올리기  (0) 2024.06.26
2D 3Matchpuzzle - 매치 시 파괴 및 로드 + 힌트  (0) 2024.05.20
2D 3Matchpuzzle - 빈공간 찾기  (0) 2024.05.14
Download Python  (0) 2024.05.08
Learn Firebase  (0) 2024.05.02

 

 

using System;
using System.Collections;
using System.Collections.Generic;
using System.Text;
using UnityEngine;
using UnityEngine.U2D;
using Random = UnityEngine.Random;

public class Test : MonoBehaviour
{
    public Board board;
    private void Start()
    {
        board.CreateBoard();
    }

    private void Update()
    {
        if (Input.GetMouseButtonDown(0))
        {
            Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
            Debug.DrawRay(ray.origin, ray.direction * 100f, Color.red, 1);
            RaycastHit2D raycastHit2D = Physics2D.Raycast(ray.origin, ray.direction);
            if (raycastHit2D.collider != null)
            {
                Block block = raycastHit2D.collider.GetComponent<Block>();
                Debug.Log($"[{block.row}, {block.col}] ({block.transform.position.x}, {block.transform.position.y}), {block.blockType}");
            }
        }
    }
}

 

using System.Collections;
using System.Collections.Generic;
using TMPro;
using UnityEngine;

public class Block : MonoBehaviour
{
    public enum BlockType
    {
        Rabbit, Pig, Rat, Monkey, Cat, Chick, Puppy
    }

    public BlockType blockType;
    public SpriteRenderer spriteRenderer;
    public TMP_Text debugText;
    public int row;
    public int col;

    public void Init(BlockType blockType)
    {
        this.blockType = blockType;
        //이미지 변경 
        ChangeSprite(blockType);
    }

    public void ChangeSprite(BlockType blockType)
    {
        Sprite sp =
            AtlasManager.instance.blockAtlas.GetSprite(blockType.ToString());
        spriteRenderer.sprite = sp;
    }

    public void SetPosition(Vector2 pos)
    {
        transform.position = pos;
        var index = Position2Index(pos);
        row = index.row;
        col = index.col;
        debugText.text = $"[{index.row},{index.col}]";
    }

    public static (int row, int col) Position2Index(Vector2 pos)
    {
        return ((int)pos.y, (int)pos.x);
    }

    public static (int x, int y) Index2Position(Vector2 index)
    {
        return ((int)index.x, (int)index.y);
    }
}

 

    using System.Collections;
    using System.Collections.Generic;
    using UnityEditor;
    using UnityEngine;

    [CustomEditor(typeof(Block))]
    public class BlockEditor : Editor
    {
        public override void OnInspectorGUI()
        {
            base.OnInspectorGUI();

            Block block = target as Block;
            if (GUILayout.Button("제거"))
            {
                Debug.Log($"[{block.row},{block.col}]을 제거 합니다.");

                Board.instance.RemoveBlock(block.row, block.col);
            }
        }
    }

 

using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using UnityEngine;
using Random = UnityEngine.Random;

public class Board : MonoBehaviour
{
    public static Board instance;   //싱글톤
    private Block[,] board;  //2차원 배열이 Block들을 관리
    public GameObject blockPrefab;

    public int totalHeight = 14;
    public int height = 7;
    public int width = 7;

    private void Awake()
    {
        instance = this;
    }

    public void CreateBoard()
    {
        //크기가 7개인 Block타입의 2차원 배열을 만들기
        board = new Block[totalHeight, width];

        for (int i = 0; i < height; i++)    //행
        {
            for (int j = 0; j < width; j++)    //열 
            {
                CreateBlock(i, j);
            }
        }
        PrintBoard();
    }

    public void CreateBlock(int row, int col)
    {
        Vector2 pos = new Vector2(col, row);
        Block.BlockType blockType = (Block.BlockType)Random.Range(0, 7); //0 ~ 6  
        GameObject blockGo = Instantiate(blockPrefab, this.transform);
        Block block = blockGo.GetComponent<Block>();
        block.Init(blockType);
        block.SetPosition(pos);

        //배열의 요소에 블록 넣기 
        board[row, col] = block;
    }

    public void RemoveBlock(int row, int col)
    {
        Block block = board[row, col];
        Destroy(block.gameObject);  //게임오브젝트 파괴 

        //배열의 요소를 비워줌 
        board[row, col] = null;
    }

    public void PrintBoard()
    {
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < height; i++)    //행
        {
            for (int j = 0; j < width; j++)    //열
            {
                Block block = board[i, j];
                string strElement = (block == null) ? "null" : block.blockType.ToString();
                // 각 엘리먼트를 고정된 너비로 출력
                sb.AppendFormat("[{0},{1}] = {2,-10}", i, j, strElement);
            }
            sb.AppendLine();
        }
        Debug.Log(sb.ToString());
    }

    private int[] arrEmptySpaceCol; //빈공간이 있는 컬럼 배열 

    public void FindEmptySpaceFromColumn()
    {
        arrEmptySpaceCol = new int[width]; //배열 초기화
                                           //0 : 행, 1: 열 
        for (int i = 0; i < width; i++)    //열 
        {
            int existBlockCnt = 0;

            for (int j = 0; j < totalHeight; j++)    //행 
            {
                Block block = board[j, i];
                if (block != null) existBlockCnt++;
            }

            int emptySpace = height - existBlockCnt;
            arrEmptySpaceCol[i] = emptySpace;
            Debug.Log($"{i} 열의 빈공간은 {emptySpace}개 입니다.");
        }
    }

    public void CreateNewBlocks()
    {
        // arrEmptySpaceCol가 null이거나 모든 요소가 0이면 빈공간이 없음
        if (arrEmptySpaceCol == null || arrEmptySpaceCol.All(x => x == 0))
        {
            Debug.Log("빈공간이 없습니다.");
        }
        else
        {
            for (int i = 0; i < arrEmptySpaceCol.Length; i++)
            {
                int cnt = arrEmptySpaceCol[i];  //i(col)에 몇개 빈공간이 있는가?
                if (cnt > 0)
                {
                    Debug.Log($"{i}열에 {cnt}만큼 블록 생성 필요");
                    CreateBlockFromColumn(i, cnt);
                }
            }
        }

        arrEmptySpaceCol = null;
    }

    private void CreateBlockFromColumn(int col, int cnt)
    {
        int startRow = height;  //행 

        for (int i = 0; i < cnt; i++)
        {
            //[7, col] -> [8, col] -> [9,col]
            CreateBlock(startRow, col);
            startRow++;
        }
    }
}

 

using System.Collections;
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;

[CustomEditor(typeof(Board))]
public class BoardEditor : Editor
{
    private int currentColIdx = 0;

    public override void OnInspectorGUI()
    {
        base.OnInspectorGUI();

        Board board = target as Board;

        if (GUILayout.Button("배열 요소 출력"))
        {
            board.PrintBoard(); ;
        }

        GUILayout.Space(5);

        if (GUILayout.Button("각 열에 빈공간 찾기"))
        {
            board.FindEmptySpaceFromColumn();
        }

        GUILayout.Space(5);

        if (GUILayout.Button("새로운 블록들 생성하기"))
        {
            board.CreateNewBlocks();
        }

        GUILayout.Space(5);
        if (GUILayout.Button($"현재 행({currentColIdx})에 있는 모든 블록 내려보내기"))
        {
            Debug.Log($"{currentColIdx}행에 있는 모든 블록 내려 보냅니다.");
            currentColIdx++;
            if (currentColIdx > 6)
            {
                currentColIdx = 0;
            }
        }
        GUILayout.Space(5);

        if (GUILayout.Button("리셋 행"))
        {
            currentColIdx = 0;
        }
    }
}

'산대특' 카테고리의 다른 글

2D 3Matchpuzzle - 매치 시 파괴 및 로드 + 힌트  (0) 2024.05.20
2D 3Matchpuzzle - 블록 위치 찾기 테스트  (0) 2024.05.16
Download Python  (0) 2024.05.08
Learn Firebase  (0) 2024.05.02
2D Vertical Shooting Game 모작 최종  (0) 2024.04.08

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

public class ActiveCard : MonoBehaviour
{
    public GameObject cardPrefab; // 인스펙터에서 프리팹을 할당하세요
    public TMP_Text valueTextPrefab; // 인스펙터에서 텍스트 프리팹을 할당하세요
    public Transform parentTransform; // 인스펙터에서 부모 변환을 할당하세요

    void Start()
    {
        PlayerManager.Instance.LoadPlayerCardData();
        PlayerManager.Instance.LoadPlayerCardInfo();
        PlayerManager.Instance.LoadPlayerCardInfoListData();

        foreach (var playerActiveCardInfo in PlayerManager.Instance.dicPlayerCardInfoList)
        {
            Debug.Log("버튼이 눌림");

            // 프리팹에서 새 카드 오브젝트를 복제합니다.
            GameObject newCard = Instantiate(cardPrefab, parentTransform);

            // 카드의 자식 오브젝트로서 새로운 TMP_Text를 생성합니다.
            TMP_Text valueText = Instantiate(valueTextPrefab, newCard.transform);

            // 값을 설정합니다.
            valueText.text = playerActiveCardInfo.Value.value.ToString();

            Debug.Log(valueText.text);
        }

        Debug.Log("데이터 개수: " + PlayerManager.Instance.dicPlayerCardInfoList.Count);
    }
}

 

 

데이터 불러오기 

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

public class ActiveCard : MonoBehaviour
{
    public TMP_Text valueTextPrefab;
    public TMP_Text cardNamePrefab;
    public TMP_Text cardInfoPrefab;
}

 

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class ActiveCardDecBtn : MonoBehaviour
{
    public Button btn;
    public GameObject ActiveCardInventory;

    public GameObject cardPrefab;
    public Transform parentTransform;
    void Start()
    {
        
            btn.onClick.AddListener(() =>
            {
                ActiveCardInventory.SetActive(true);
            });


        List<PlayerCardInfo> card = new List<PlayerCardInfo>(PlayerManager.Instance.dicPlayerCardInfo.Values);



        for (int i = 0; i < PlayerManager.Instance.dicPlayerCardInfoList.Count; i++)
        {
            Debug.Log("버튼이 눌림");

            // 프리팹에서 새 카드 오브젝트를 생성
            GameObject Card = Instantiate(cardPrefab, parentTransform);
            ActiveCard newCard = Card.GetComponent<ActiveCard>();


            // 값을 설정
            newCard.valueTextPrefab.text = card[i].value.ToString();

            newCard.cardNamePrefab.text = card[i].card_name;

            newCard.cardInfoPrefab.text = PlayerManager.Instance.dicPlayerCardDatas[card[i].card_original_id].desc;
        }

    }

    void Update()
    {

    }
}

https://www.immersivelimit.com/tutorials/reinforcement-learning-penguins-part-1-unity-ml-agents

 

Reinforcement Learning Penguins (Part 1/4) | Unity ML-Agents — Immersive Limit

Unity Project Setup and Asset Import

www.immersivelimit.com

 

 

 

 

https://docs.unity3d.com/ScriptReference/TooltipAttribute.html

 

Unity - Scripting API: TooltipAttribute

Tooltip hovering over the class it was added to. In the following script a Tooltip is added. This provides information to the user about the range of values for the health variable. The suggested range is provided in the TooltipAttribute string. Note: Unit

docs.unity3d.com

https://docs.unity3d.com/Packages/com.unity.ml-agents@3.0/api/Unity.MLAgents.Agent.GetCumulativeReward.html

 

Method GetCumulativeReward | ML Agents | 3.0.0-exp.1

Method GetCumulativeReward GetCumulativeReward() Retrieves the episode reward for the Agent. Declaration public float GetCumulativeReward() Returns Type Description float The episode reward.

docs.unity3d.com

 

using System.Collections;
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;

[CustomEditor(typeof(PenguinArea))]
public class PenguinAreaEditor : Editor
{
    public override void OnInspectorGUI()
    {
        PenguinArea penguinArea = (PenguinArea)target;
        base.OnInspectorGUI();
        if (GUILayout.Button("Choose Random Position"))
        {
            Debug.Log("ChooseRandomPosition");
            Vector3 center = penguinArea.transform.position;
            float minAngle = -15;
            float maxAngle = 15;
            float minRadius = 1;
            float maxRadius = 2;
            Vector3 randPos =
                PenguinArea.ChooseRandomPosition(center, minAngle, maxAngle, minRadius, maxRadius);

            Debug.Log(randPos);

            Debug.DrawLine(center, randPos, Color.red, 10);
        }
    }
}

 

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using TMPro;

public class PenguinArea : MonoBehaviour
{
    [Tooltip("The agent inside the area")]
    public PenguinAgent penguinAgent;

    [Tooltip("The baby penguin inside the area")]
    public GameObject penguinBaby;

    [Tooltip("The TextMeshPro text that shows the cumulative reward of the agent")]
    public TextMeshPro cumulativeRewardText;

    [Tooltip("Prefab of a live fish")]
    public Fish fishPrefab;

    private List<GameObject> fishList;

    //씬에 남아 있는 물고기 수 

    public int FishRemaining
    {
        get { return fishList.Count; }
    }

    private void Start()
    {
        this.fishList = new List<GameObject>();

        ResetArea();
    }

    private void Update()
    {
        // Update the cumulative reward text
        cumulativeRewardText.text = penguinAgent.GetCumulativeReward().ToString("0.00");
    }


    public void ResetArea()
    {
        RemoveAllFish();
        PlacePenguin();
        PlaceBaby();
        SpawnFish(4, .5f);
    }

    //엄마 펭귄의 이동속도, 회전속도 초기화 및 랜덤위치, 랜덤회전
    private void PlacePenguin()
    {
        Rigidbody rigidbody = penguinAgent.GetComponent<Rigidbody>();
        rigidbody.velocity = Vector3.zero;
        rigidbody.angularVelocity = Vector3.zero;
        penguinAgent.transform.position = ChooseRandomPosition(transform.position, 0f, 360f, 0f, 9f) + Vector3.up * .5f;
        penguinAgent.transform.rotation = Quaternion.Euler(0f, UnityEngine.Random.Range(0f, 360f), 0f);
    }

    private void PlaceBaby()
    {
        Rigidbody rigidbody = penguinBaby.GetComponent<Rigidbody>();
        rigidbody.velocity = Vector3.zero;
        rigidbody.angularVelocity = Vector3.zero;
        penguinBaby.transform.position = ChooseRandomPosition(transform.position, -45f, 45f, 4f, 9f) + Vector3.up * .5f;
        penguinBaby.transform.rotation = Quaternion.Euler(0f, 180f, 0f);
    }


    //물고기를 먹었다면 리스트에서 제거하고 씬에서 제거한다 
    public void RemoveSpecificFish(GameObject fishObject)
    {
        fishList.Remove(fishObject);
        Destroy(fishObject);
    }

    public static Vector3 ChooseRandomPosition(Vector3 center, float minAngle, float maxAngle, float minRadius, float maxRadius)
    {
        float radius = minRadius;
        float angle = minAngle;

        if (maxRadius > minRadius)
        {
            // Pick a random radius
            radius = UnityEngine.Random.Range(minRadius, maxRadius);
        }

        if (maxAngle > minAngle)
        {
            // Pick a random angle
            angle = UnityEngine.Random.Range(minAngle, maxAngle);
        }

        // Center position + forward vector rotated around the Y axis by "angle" degrees, multiplies by "radius"
        return center + Quaternion.Euler(0f, angle, 0f) * Vector3.forward * radius;
    }

    //count만큼 fish프리팹 인스턴스 생성, 리스트에 넣기, 이동속도 설정하기 
    private void SpawnFish(int count, float fishSpeed)
    {
        for (int i = 0; i < count; i++)
        {
            // Spawn and place the fish
            GameObject fishObject = Instantiate<GameObject>(fishPrefab.gameObject);
            fishObject.transform.position = ChooseRandomPosition(transform.position, 100f, 260f, 2f, 13f) + Vector3.up * .5f;
            fishObject.transform.rotation = Quaternion.Euler(0f, UnityEngine.Random.Range(0f, 360f), 0f);

            // Set the fish's parent to this area's transform
            fishObject.transform.SetParent(transform);

            // Keep track of the fish
            fishList.Add(fishObject);

            // Set the fish speed
            fishObject.GetComponent<Fish>().fishSpeed = fishSpeed;
        }
    }

    private void RemoveAllFish()
    {
        if (fishList != null)
        {
            for (int i = 0; i < fishList.Count; i++)
            {
                if (fishList[i] != null)
                {
                    Destroy(fishList[i]);
                }
            }
        }

        fishList = new List<GameObject>();
    }

    private void OnDrawGizmos()
    {
        Vector3 center = this.transform.position;
        Vector3 dir = Vector3.forward;
        float angleRange = 30f;
        float radius = 2f;

        GizmosExtensions.DrawWireArc(center, dir, angleRange, radius);
    }
}

 

using UnityEngine;

public class GizmosExtensions
{
    private GizmosExtensions() { }

    public static void DrawWireArc(Vector3 position, Vector3 dir, float anglesRange, float radius, Color color, float maxSteps = 20)
    {
        Gizmos.color = color;

        var srcAngles = GetAnglesFromDir(position, dir);
        var initialPos = position;
        var posA = initialPos;
        var stepAngles = anglesRange / maxSteps;
        var angle = srcAngles - anglesRange / 2;
        for (var i = 0; i <= maxSteps; i++)
        {
            var rad = Mathf.Deg2Rad * angle;
            var posB = initialPos;
            posB += new Vector3(radius * Mathf.Cos(rad), radius * Mathf.Sin(rad), 0);

            Gizmos.DrawLine(posA, posB);

            angle += stepAngles;
            posA = posB;
        }
        Gizmos.DrawLine(posA, initialPos);
    }


    /// <summary>
    /// Draws a wire arc.
    /// </summary>
    /// <param name="position"></param>
    /// <param name="dir">The direction from which the anglesRange is taken into account</param>
    /// <param name="anglesRange">The angle range, in degrees.</param>
    /// <param name="radius"></param>
    /// <param name="maxSteps">How many steps to use to draw the arc.</param>
    public static void DrawWireArc(Vector3 position, Vector3 dir, float anglesRange, float radius, float maxSteps = 20)
    {
        var srcAngles = GetAnglesFromDir(position, dir);
        var initialPos = position;
        var posA = initialPos;
        var stepAngles = anglesRange / maxSteps;
        var angle = srcAngles - anglesRange / 2;
        for (var i = 0; i <= maxSteps; i++)
        {
            var rad = Mathf.Deg2Rad * angle;
            var posB = initialPos;
            posB += new Vector3(radius * Mathf.Cos(rad), 0, radius * Mathf.Sin(rad));

            Gizmos.DrawLine(posA, posB);

            angle += stepAngles;
            posA = posB;
        }
        Gizmos.DrawLine(posA, initialPos);
    }

    static float GetAnglesFromDir(Vector3 position, Vector3 dir)
    {
        var forwardLimitPos = position + dir;
        var srcAngles = Mathf.Rad2Deg * Mathf.Atan2(forwardLimitPos.z - position.z, forwardLimitPos.x - position.x);

        return srcAngles;
    }
}

 

using System.Collections;
using System.Collections.Generic;
using Unity.MLAgents;
using Unity.MLAgents.Actuators;
using Unity.MLAgents.Sensors;
using UnityEngine;

public class PenguinAgent : Agent
{
    [Tooltip("How fast the agent moves forward")]
    public float moveSpeed = 5f;

    [Tooltip("How fast the agent turns")]
    public float turnSpeed = 180f;

    [Tooltip("Prefab of the heart that appears when the baby is fed")]
    public GameObject heartPrefab;

    [Tooltip("Prefab of the regurgitated fish that appears when the baby is fed")]
    public GameObject regurgitatedFishPrefab;

    private PenguinArea penguinArea;
    new private Rigidbody rigidbody;
    private GameObject baby;
    private bool isFull; // If true, penguin has a full stomach

    public override void Initialize()
    {
        base.Initialize();
        penguinArea = GetComponentInParent<PenguinArea>();
        baby = penguinArea.penguinBaby;
        rigidbody = GetComponent<Rigidbody>();
    }
    public override void OnActionReceived(ActionBuffers actionBuffers)
    {
        // Convert the first action to forward movement
        float forwardAmount = actionBuffers.DiscreteActions[0];

        // Convert the second action to turning left or right
        float turnAmount = 0f;
        if (actionBuffers.DiscreteActions[1] == 1f)
        {
            turnAmount = -1f;
        }
        else if (actionBuffers.DiscreteActions[1] == 2f)
        {
            turnAmount = 1f;
        }

        // Apply movement
        rigidbody.MovePosition(transform.position + transform.forward * forwardAmount * moveSpeed * Time.fixedDeltaTime);
        transform.Rotate(transform.up * turnAmount * turnSpeed * Time.fixedDeltaTime);

        // Apply a tiny negative reward every step to encourage action
        if (MaxStep > 0) AddReward(-1f / MaxStep);
    }

    public override void Heuristic(in ActionBuffers actionsOut)
    {
        int forwardAction = 0;
        int turnAction = 0;
        if (Input.GetKey(KeyCode.W))
        {
            // move forward
            forwardAction = 1;
        }
        if (Input.GetKey(KeyCode.A))
        {
            // turn left
            turnAction = 1;
        }
        else if (Input.GetKey(KeyCode.D))
        {
            // turn right
            turnAction = 2;
        }

        // Put the actions into the array
        actionsOut.DiscreteActions.Array[0] = forwardAction;
        actionsOut.DiscreteActions.Array[1] = turnAction;
    }
    public override void OnEpisodeBegin()
    {
        isFull = false;
        penguinArea.ResetArea();
    }
    public override void CollectObservations(VectorSensor sensor)
    {
        // Whether the penguin has eaten a fish (1 float = 1 value)
        sensor.AddObservation(isFull);

        // Distance to the baby (1 float = 1 value)
        sensor.AddObservation(Vector3.Distance(baby.transform.position, transform.position));

        // Direction to baby (1 Vector3 = 3 values)
        sensor.AddObservation((baby.transform.position - transform.position).normalized);

        // Direction penguin is facing (1 Vector3 = 3 values)
        sensor.AddObservation(transform.forward);

        // 1 + 1 + 3 + 3 = 8 total values
    }
    private void OnCollisionEnter(Collision collision)
    {
        if (collision.transform.CompareTag("fish"))
        {
            // Try to eat the fish
            EatFish(collision.gameObject);
        }
        else if (collision.transform.CompareTag("baby"))
        {
            // Try to feed the baby
            RegurgitateFish();
        }
    }
    private void EatFish(GameObject fishObject)
    {
        if (isFull) return; // Can't eat another fish while full
        isFull = true;

        penguinArea.RemoveSpecificFish(fishObject);

        AddReward(1f);
    }

    private void RegurgitateFish()
    {
        if (!isFull) return; // Nothing to regurgitate
        isFull = false;

        // Spawn regurgitated fish
        GameObject regurgitatedFish = Instantiate<GameObject>(regurgitatedFishPrefab);
        regurgitatedFish.transform.parent = transform.parent;
        regurgitatedFish.transform.position = baby.transform.position;
        Destroy(regurgitatedFish, 4f);

        // Spawn heart
        GameObject heart = Instantiate<GameObject>(heartPrefab);
        heart.transform.parent = transform.parent;
        heart.transform.position = baby.transform.position + Vector3.up;
        Destroy(heart, 4f);

        AddReward(1f);

        if (penguinArea.FishRemaining <= 0)
        {
            EndEpisode();
        }
    }


}

 

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

public class Fish : MonoBehaviour
{
    [Tooltip("The swim speed")]
    public float fishSpeed;

    private float randomizedSpeed = 0f;
    private float nextActionTime = -1f;
    private Vector3 targetPosition;

    private void FixedUpdate()
    {
        if (fishSpeed > 0f)
        {
            Swim();
        }
    }

    private void Swim()
    {
        // If it's time for the next action, pick a new speed and destination
        // Else, swim toward the destination
        if (Time.fixedTime >= nextActionTime)
        {
            // Randomize the speed
            randomizedSpeed = fishSpeed * UnityEngine.Random.Range(.5f, 1.5f);

            // Pick a random target
            targetPosition = PenguinArea.ChooseRandomPosition(transform.parent.position, 100f, 260f, 2f, 13f);

            // Rotate toward the target
            transform.rotation = Quaternion.LookRotation(targetPosition - transform.position, Vector3.up);

            // Calculate the time to get there
            float timeToGetThere = Vector3.Distance(transform.position, targetPosition) / randomizedSpeed;
            nextActionTime = Time.fixedTime + timeToGetThere;
        }
        else
        {
            // Make sure that the fish does not swim past the target
            Vector3 moveVector = randomizedSpeed * transform.forward * Time.fixedDeltaTime;
            if (moveVector.magnitude <= Vector3.Distance(transform.position, targetPosition))
            {
                transform.position += moveVector;
            }
            else
            {
                transform.position = targetPosition;
                nextActionTime = Time.fixedTime;
            }
        }
    }
}

https://github.com/Unity-Technologies/ml-agents/blob/develop/docs/Getting-Started.md

 

ml-agents/docs/Getting-Started.md at develop · Unity-Technologies/ml-agents

The Unity Machine Learning Agents Toolkit (ML-Agents) is an open-source project that enables games and simulations to serve as environments for training intelligent agents using deep reinforcement ...

github.com

https://github.com/Unity-Technologies/ml-agents/blob/develop/docs/Learning-Environment-Create-New.md

 

ml-agents/docs/Learning-Environment-Create-New.md at develop · Unity-Technologies/ml-agents

The Unity Machine Learning Agents Toolkit (ML-Agents) is an open-source project that enables games and simulations to serve as environments for training intelligent agents using deep reinforcement ...

github.com

경로 창에 cmd를 입력하고 엔터를 누르면 이 창에 들어온다.

 

pip install attrs==23.2.0 cattrs==1.5.0 h5py==3.11.0 huggingface-hub==0.23.0 onnx==1.15.0 pypiwin32==223 tensorboard==2.16.2 mlagents-envs==1.1.0.dev0 protobuf==3.20.3 absl-py==2.1.0 --no-deps

 

오류가 나면

버전을 정하지 않고 설치

python -m pip install mlagents

 

mlagents-learn config/ppo/3DBall.yaml --run-id=first3DBallRun

생성이 되면 지우고 다시 설치 후 플레이를 하면 학습을 한다.

 

mlagents-learn config/ppo/3DBall.yaml --run-id=first3DBallRun

 

cmd창에서 컨트롤 + C 누르면 중지

 

중지 후 시간이 지나면 이렇게 학습된 기록들이 만들어진다.

 

 

https://github.com/Unity-Technologies/ml-agents/blob/develop/docs/Installation.md

 

ml-agents/docs/Installation.md at develop · Unity-Technologies/ml-agents

The Unity Machine Learning Agents Toolkit (ML-Agents) is an open-source project that enables games and simulations to serve as environments for training intelligent agents using deep reinforcement ...

github.com

 

https://github.com/adang1345/PythonWindows/blob/master/3.10.12/python-3.10.12-amd64-full.exe

 

PythonWindows/3.10.12/python-3.10.12-amd64-full.exe at master · adang1345/PythonWindows

Unofficial Python installers for Windows. Contribute to adang1345/PythonWindows development by creating an account on GitHub.

github.com

 

폴더를 만들어주고 결로를 지정해준다.

cmd를 켠 후 검색하면 찾을 수 있다.

pip3 install torch~=2.2.1 --index-url https://download.pytorch.org/whl/cu121

 

https://download.pytorch.org/whl/cu121

 

download.pytorch.org

pip install numpy==1.23.3

 

 

하지만 여기서 뒤에 더 추가해야 한다.

python -m pip install mlagents==1.0.0 --no-deps

 

git clone --branch release_21 https://github.com/Unity-Technologies/ml-agents.git

 

GitHub - Unity-Technologies/ml-agents: The Unity Machine Learning Agents Toolkit (ML-Agents) is an open-source project that enab

The Unity Machine Learning Agents Toolkit (ML-Agents) is an open-source project that enables games and simulations to serve as environments for training intelligent agents using deep reinforcement ...

github.com

 

 

소스트리를 활용하여 클론

 

유니티 허브에서 add를 한다.

 

패키지매니저를 열고 TextMeshPro를 설치하면 에러 2줄이 해결된다.

 

 

 

 

 

 

'산대특' 카테고리의 다른 글

2D 3Matchpuzzle - 블록 위치 찾기 테스트  (0) 2024.05.16
2D 3Matchpuzzle - 빈공간 찾기  (0) 2024.05.14
Learn Firebase  (0) 2024.05.02
2D Vertical Shooting Game 모작 최종  (0) 2024.04.08
팬텀로즈스칼렛 모작 최종  (0) 2024.04.08

+ Recent posts