2022년 10월 27일 목요일

ml agent unity 초기 설정방법(anaconda,Window)



1. Unity 설치 (2020.3이상)


  


2. anaconda 설치


  


3.가상환경 만들기


  

- conda create -n MLAgent python =3.7.9


  

  


4. 해당 가상환경에 pytorch설치


## pip3 install torch~=1.7.1 -f https://download.pytorch.org/whl/torch_stable.html


  





![[Pasted image 20221030163156.png]]




5. 해당 가상환경에 mlagent 설치


## python -m pip install mlagents==0.28.0


![[Pasted image 20221030163252.png]]


2022년 10월 26일 수요일

unity 2d sprite animation

 


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

[Serializable]
public struct SpriteInfo
{
    public Image sourceImage;
    public Sprite[] textureArray;
    public float frameRate;
   
}

public class SpriteAnimation : MonoBehaviour
{

    [SerializeField] SpriteInfo s_Info;


    [SerializeField] float frameTimer;
    [SerializeField] int currentFrame;
    [SerializeField] int frameCount;



    // Start is called before the first frame update
    void Start()
    {
       
    }

    // Update is called once per frame
    void Update()
    {
        if (Input.GetKeyDown("1"))
        {
            StartCoroutine(StartSprite(s_Info));
        }
    }



    IEnumerator StartSprite(SpriteInfo info)
    {
        frameTimer = info.frameRate;
        frameCount = info.textureArray.Length;

        //Rect rect = new Rect(0, 0, info.textureArray[0].width, info.textureArray[0].height);

        while (true)
        {
            frameTimer -= Time.deltaTime;
            if (frameTimer <= 0f)
            {
                frameTimer += info.frameRate;
                currentFrame = (currentFrame + 1) % frameCount;
                info.sourceImage.sprite = info.textureArray[currentFrame];
                Debug.Log(info.sourceImage.sprite.name);
                //info.sourceImage.sprite = Sprite.Create(info.textureArray[currentFrame],rect,Vector2.zero);
            }
            yield return new WaitForEndOfFrame();
        }
    }


}






2022년 10월 20일 목요일

TryGetComponent Unity

 



using UnityEngine;

public class TryGetComponentExample : MonoBehaviour
{
    void Start()
    {
        if (TryGetComponent(out HingeJoint hinge))
        {
            hinge.useSpring = false;
        }
    }
}



2022년 10월 19일 수요일

Unity animation use Slider UI

 


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

public class AnimationTruck : MonoBehaviour
{
    public Animation ani;
    public string clip_name;
    public float ani_time;

    [Header("Animation Slider")]
    [SerializeField] Slider AnimationSlider;
    [SerializeField] float speed;

    private void Start()
    {
        Hide();
        if (AnimationSlider != null)
        {
            AnimationSlider.maxValue = ani[clip_name].length;

           

            AnimationSlider.onValueChanged.AddListener(delegate
            { OnChangeAnimationBySlider(AnimationSlider);
            });

        }
    }



    void OnChangeAnimationBySlider(Slider slider)
    {
        if (!ani.isPlaying)
        {
            ani.Play();
            ani[clip_name].speed = 0;
        }

        //ani[clip_name].speed = speed;
        ani[clip_name].time = slider.value;

    }


    public void ToggleAnimation(Toggle m_toggle)
    {
        if (m_toggle.isOn)
        {
            Show();
        }
        else
        {
            Hide();
        }
    }

    private void Update()
    {
        if (AnimationSlider == null)
                return;
        
            if (AnimationSlider.value != ani[clip_name].time)
            {
                AnimationSlider.value =  ani[clip_name].time;
            }
    }

    public void Hide()
    {
        //if (ani_time == ani[clip_name].length)
        //    return;

        ani_time = ani[clip_name].time;

        func_playAni(ani_time, clip_name);

    }
    public void Show()
    {

        if (ani_time == 0)
            ani_time = ani[clip_name].length;
        else
            ani_time = ani[clip_name].time;


        func_reversPlay(ani_time, clip_name);

    }


    public void func_playAni(float time, string aniName)
    {

        ani[aniName].time = time;
        ani[aniName].speed = speed;
        ani.Play();

    }

    public void func_reversPlay(float time, string aniName)
    {
        ani[aniName].time = time;
        ani[aniName].speed = -speed;
        ani.Play();
    }
}





2022년 10월 16일 일요일

searchBox.cs

 



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

public class SearchDropBoxInit : MonoBehaviour
{

    [SerializeField] TMP_Dropdown dr_car;
    [SerializeField] TMP_Dropdown dr_company;
    [SerializeField] TMP_Dropdown dr_product;

    [SerializeField] SearchDropBoxOpen uic_car;
    [SerializeField] SearchDropBoxOpen uic_company;
    [SerializeField] SearchDropBoxOpen uic_product;


    [SerializeField] TextMeshProUGUI txt_result_car;
    [SerializeField] TextMeshProUGUI txt_result_company;
    [SerializeField] TextMeshProUGUI txt_result_product;

    [Header("Scrollview")]
    [SerializeField] CompanyItemTableViewController m_CompanyItemTableViewController;
    [Header("Search")]
    [SerializeField] TMP_InputField m_TMP_InputField;

    List<CompanyUiItem> originTable;
    // Start is called before the first frame update
    void Start()
    {
        StartCoroutine(InitData());
        StartCoroutine(InitScrollView());
    }

    IEnumerator InitData()
    {
        yield return new WaitUntil(() => LoadPartLinksWebGL.Instance.m_xmlLoadDatas.m_dataCarsXml.data.Count != 0);
        SetFunction_UI(dr_car, LoadPartLinksWebGL.Instance.m_xmlLoadDatas.m_dataCarsXml.data, uic_car, txt_result_car);
        SetFunction_UI(dr_company, LoadPartLinksWebGL.Instance.m_xmlLoadDatas.m_dataCompanysXml.data, uic_company, txt_result_company);
        SetFunction_UI(dr_product, LoadPartLinksWebGL.Instance.m_xmlLoadDatas.m_dataProductsXml.data, uic_product, txt_result_product);
    }

    IEnumerator InitScrollView()
    {
        yield return new WaitUntil(() => LoadPartLinksWebGL.Instance.m_AllProgramPath.links.Count != 0);
        SetScrollview();

        //m_TMP_InputField.onEndEdit.AddListener(ValueChanged);
        m_TMP_InputField.onValueChanged.AddListener(ValueChanged);
    }


    void SetScrollview()
    {

        originTable = new List<CompanyUiItem>();

       
        foreach (var x in LoadPartLinksWebGL.Instance.m_AllProgramPath.links)
        {
            CompanyUiItem temp = new CompanyUiItem();

            ///회사이름이 없으면 일반씬이므로 컨티뉴
            if (x.Value.companyName == "")
                continue;

            temp.companyName = x.Value.companyName;
            temp.companyType = x.Value.companyType;
            temp.url = x.Value.url;
            temp.products = x.Value.products;
            temp.cars = x.Value.targetCar;
            originTable.Add(temp);
        }
        m_CompanyItemTableViewController.UpdateData(originTable);

    }


    #region 검색
    public List<CompanyUiItem> SearchTableData(string input)
    {
        if (input.Length == 0)
            return originTable;




        input = input.Replace(",", ""); ///따움표는 없는걸로 체크


        Func<CompanyUiItem,bool> condition_car; //검색 조건
        Func<CompanyUiItem, bool> condition_products; //검색 조건
        Func<CompanyUiItem, bool> condition_companyName; //검색 조건
        Func<CompanyUiItem, bool> condition_companyType; //검색 조건
       
        //Func<CompanyUiItem, object> order; //정렬 기준
        string search = input.ToLower(); //소문자로 변환

        condition_car = item => item.cars.Where(x=> x.ToLower().Contains(search)).Any();
        condition_products = item => item.products.Where(x => x.ToLower().Contains(search)).Any();
        condition_companyName = item => item.companyName.ToLower().Contains(search);
        condition_companyType = item => item.companyType.ToLower().Contains(search);






       
        IEnumerable<CompanyUiItem> result_car;
        IEnumerable<CompanyUiItem> result_products;
        IEnumerable<CompanyUiItem> result_company;
        IEnumerable<CompanyUiItem> result_type;

        result_car = originTable.Where(condition_car);
        result_products = originTable.Where(condition_products);
        result_company = originTable.Where(condition_companyName);
        result_type = originTable.Where(condition_companyType);

        //result = originTable.Where(condition_car).Where(condition_companyName).Where(condition_companyType).Where(condition_products);
        result_car = result_car.Select(x => new CompanyUiItem
        {
            companyName = x.companyName,
            companyType = x.companyType,
            cars = x.cars,
            products = x.products,
            url = x.url,
        });
        result_products = result_products.Select(x => new CompanyUiItem
        {
            companyName = x.companyName,
            companyType = x.companyType,
            cars = x.cars,
            products = x.products,
            url = x.url,
        });
        result_company = result_company.Select(x => new CompanyUiItem
        {
            companyName = x.companyName,
            companyType = x.companyType,
            cars = x.cars,
            products = x.products,
            url = x.url,
        });
        result_type = result_type.Select(x => new CompanyUiItem
        {
            companyName = x.companyName,
            companyType = x.companyType,
            cars = x.cars,
            products = x.products,
            url = x.url,
        });

        IEnumerable<CompanyUiItem> result  =
            new[] { result_car, result_products, result_company, result_type }.
            Where(x=>x!=null).
            SelectMany(x => x).
            Distinct();
        return result.ToList();
    }


    void ValueChanged(string text)
    {

        string[] texts = text.Split(",");


        if (texts.Length == 0)
        {
            m_CompanyItemTableViewController.UpdateData(SearchTableData(text));
        }
        else
        {
            List<CompanyUiItem> result = new List<CompanyUiItem>();
            foreach (var x in texts)
                result.AddRange(SearchTableData(x));

            m_CompanyItemTableViewController.UpdateData(result);
        }
    }

    #endregion




    #region 드롭다운
    private void SetFunction_UI(TMP_Dropdown dropdown,List<string> data, SearchDropBoxOpen uic,TextMeshProUGUI result)
    {
        //Reset
        ResetFunction_UI(dropdown, data);


        // Set Default Value
        result.text = dropdown.options[dropdown.value].text;


        dropdown.onValueChanged.AddListener(delegate {
            Function_Dropdown(dropdown, uic, result);
        });
    }

    //private void Function_Button()
    //{
    //    string op = dropdown.options[dropdown.value].text;
    //    result.text = op;
    //    result_img.sprite = dropdown.options[dropdown.value].image;
    //    Debug.LogError("Dropdown Result!\n" + op);
    //}
    private void Function_Dropdown(TMP_Dropdown select, SearchDropBoxOpen uic, TextMeshProUGUI result)
    {
        string op = select.options[select.value].text;
        //message.text = op;
        Debug.Log("Dropdown Change!\n" + op);
        result.text = op;
        uic.Hide();
    }

    private void ResetFunction_UI(TMP_Dropdown dropdown,List<string> data)
    {
       
        dropdown.onValueChanged.RemoveAllListeners();
        dropdown.options.Clear();

        for (int i = 0; i < data.Count; i++)
        {
            int idx = i;
            TMP_Dropdown.OptionData newData = new TMP_Dropdown.OptionData();
            newData.text = data[idx];
            //newData.image = sprites[i];
            dropdown.options.Add(newData);
        }
        dropdown.SetValueWithoutNotify(-1);
        dropdown.SetValueWithoutNotify(0);

    }

    #endregion

}





2022년 10월 7일 금요일

Game Event (Unity,ScriptableObject)

 


https://drive.google.com/file/d/1wYwdK6P3bS1nzN_WYtdIq2Bg0gGmYY1o/view?usp=sharing


################### 간단한 INVOKE 코드
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;

public class ClickTheMinimap : MonoBehaviour,IPointerClickHandler
{

    [SerializeField] GameEvent _onClickMinimap;

    public void OnPointerClick(PointerEventData eventData)
    {
        _onClickMinimap.Invoke();
    }

}

################### 간단한 INVOKE 코드










################### 스크립터블 오브젝트
using System.Collections;
using System.Collections.Generic;
using UnityEngine;


[CreateAssetMenu(menuName ="Game Event",fileName="new Game Event")]
public class GameEvent : ScriptableObject
{

    /// <summary>
    /// HashSet 을 사용하면 중복을 피할수 있다
    /// </summary>
    HashSet<GameEventListener> _listeners = new HashSet<GameEventListener>();
    // Start is called before the first frame update
    public void Invoke()
    {
        foreach (var globalEventListener in _listeners)
            globalEventListener.RaiseEvent();
    }

    public void Register(GameEventListener gameEventListener) => _listeners.Add(gameEventListener);

    public void DeRegister(GameEventListener gameEventListener) => _listeners.Remove(gameEventListener);
}

################### 스크립터블 오브젝트





################### GameEventListener
using UnityEngine;
using UnityEngine.Events;

public class GameEventListener : MonoBehaviour
{
    [SerializeField] protected GameEvent _gameEvent;
    [SerializeField] protected UnityEvent _unityEvent;


    private void Awake()
    {
        _gameEvent.Register(gameEventListener: this);

    }
    private void OnDestroy()
    {
        _gameEvent.DeRegister(gameEventListener: this);
    }

    public virtual void RaiseEvent() => _unityEvent.Invoke();
}

################### GameEventListener





################### GameEventListener 변형버전

using System.Collections;
using UnityEngine;
using UnityEngine.Events ;

public class GameEventListenerWithDelay : GameEventListener
{

    [SerializeField] float _delay = 1f;
    [SerializeField] UnityEvent _delayedUnityEvent;

    public override void RaiseEvent()
    {
        _unityEvent.Invoke();
        StartCoroutine(RunDelayedEvent());
    }

    IEnumerator RunDelayedEvent()
    {
        yield return new WaitForSeconds(_delay);
        _delayedUnityEvent.Invoke();
    }

}

################### GameEventListener 변형버전






   GameEvent 생성 -> 스크립터블 오브젝트라 생성해놓고 사용하면 된다.





EventListner 등록해놓고 원하는 GameEvent를 등록


invoke하면 

각자 등록된 UnityEvent를 실행







git rejected error(feat. cherry-pick)

 문제 아무 생각 없이 pull을 받지않고 로컬에서 작업! 커밋, 푸시 진행을 해버렷다. push에선 remote와 다르니 당연히 pull을 진행해라고 하지만 로컬에서 작업한 내용을 백업하지 않고 진행하기에는 부담스럽다(로컬작업 유실 가능성) 해결하려...