<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: blacOOil</title>
    <description>The latest articles on DEV Community by blacOOil (@blacooil).</description>
    <link>https://dev.to/blacooil</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1398409%2F1e50df20-f0d4-41dd-a5ca-9cdf25c24b92.png</url>
      <title>DEV Community: blacOOil</title>
      <link>https://dev.to/blacooil</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/blacooil"/>
    <language>en</language>
    <item>
      <title>Machine learning ขับรถใน Unity ด้วย Python</title>
      <dc:creator>blacOOil</dc:creator>
      <pubDate>Sat, 06 Apr 2024 08:57:15 +0000</pubDate>
      <link>https://dev.to/blacooil/machine-learning-khabrthain-unity-dwy-python-25of</link>
      <guid>https://dev.to/blacooil/machine-learning-khabrthain-unity-dwy-python-25of</guid>
      <description>&lt;div class="crayons-card c-embed text-styles text-styles--secondary"&gt;
    &lt;a href="https://blackoil.itch.io/selfdrivingcar" rel="noopener noreferrer"&gt;
      blackoil.itch.io
    &lt;/a&gt;
&lt;/div&gt;
&lt;br&gt;
self-driving car ในเกมมีความสามารถในการเรียนรู้ปรับตัว และสามารถขับรถให้เก่งขึ้นได้จากการใช้ machine learning ถายในเกมของ Unity 

&lt;p&gt;ขั้นแรก ตัวรถต้องสามารถ ขยับได้ด้วยตัวเองก่อนโดยใช้โคด&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class CarDriver : MonoBehaviour {

    #region Fields
    private float speed;
    public float speedMax = 70f;
    private float speedMin = -50f;
    public float acceleration = 30f;
    public float brakeSpeed = 100f;
    private float reverseSpeed = 30f;
    private float idleSlowdown = 10f;

    private float turnSpeed;
    public float turnSpeedMax = 300f;
    private float turnSpeedAcceleration = 300f;
    private float turnIdleSlowdown = 500f;

    private float forwardAmount;
    private float turnAmount;

    private Rigidbody carRigidbody;
    #endregion

    private void Awake() {
        carRigidbody = GetComponent&amp;lt;Rigidbody&amp;gt;();
    }

    private void Update() {
        if (forwardAmount &amp;gt; 0) {
            // Accelerating
            speed += forwardAmount * acceleration * Time.deltaTime;
        }
        if (forwardAmount &amp;lt; 0) {
            if (speed &amp;gt; 0) {
                // Braking
                speed += forwardAmount * brakeSpeed * Time.deltaTime;
            } else {
                // Reversing
                speed += forwardAmount * reverseSpeed * Time.deltaTime;
            }
        }

        if (forwardAmount == 0) {
            // Not accelerating or braking
            if (speed &amp;gt; 0) {
                speed -= idleSlowdown * Time.deltaTime;
            }
            if (speed &amp;lt; 0) {
                speed += idleSlowdown * Time.deltaTime;
            }
        }

        speed = Mathf.Clamp(speed, speedMin, speedMax);

        carRigidbody.velocity = transform.forward * speed;

        if (speed &amp;lt; 0) {
            // Going backwards, invert wheels
            turnAmount = turnAmount * -1f;
        }

        if (turnAmount &amp;gt; 0 || turnAmount &amp;lt; 0) {
            // Turning
            if ((turnSpeed &amp;gt; 0 &amp;amp;&amp;amp; turnAmount &amp;lt; 0) || (turnSpeed &amp;lt; 0 &amp;amp;&amp;amp; turnAmount &amp;gt; 0)) {
                // Changing turn direction
                float minTurnAmount = 20f;
                turnSpeed = turnAmount * minTurnAmount;
            }
            turnSpeed += turnAmount * turnSpeedAcceleration * Time.deltaTime;
        } else {
            // Not turning
            if (turnSpeed &amp;gt; 0) {
                turnSpeed -= turnIdleSlowdown * Time.deltaTime;
            }
            if (turnSpeed &amp;lt; 0) {
                turnSpeed += turnIdleSlowdown * Time.deltaTime;
            }
            if (turnSpeed &amp;gt; -1f &amp;amp;&amp;amp; turnSpeed &amp;lt; +1f) {
                // Stop rotating
                turnSpeed = 0f;
            }
        }

        float speedNormalized = speed / speedMax;
        float invertSpeedNormalized = Mathf.Clamp(1 - speedNormalized, .75f, 1f);

        turnSpeed = Mathf.Clamp(turnSpeed, -turnSpeedMax, turnSpeedMax);

        carRigidbody.angularVelocity = new Vector3(0, turnSpeed * (invertSpeedNormalized * 1f) * Mathf.Deg2Rad, 0);

        if (transform.eulerAngles.x &amp;gt; 2 || transform.eulerAngles.x &amp;lt; -2 || transform.eulerAngles.z &amp;gt; 2 || transform.eulerAngles.z &amp;lt; -2) {
            transform.eulerAngles = new Vector3(0, transform.eulerAngles.y, 0);
        }
    }

    //private void OnCollisionEnter(Collision collision) {
      //  if (collision.gameObject.layer == GameHandler.SOLID_OBJECTS_LAYER) {
        //    speed = Mathf.Clamp(speed, 0f, 20f);
        //}
    //}

    public void SetInputs(float forwardAmount, float turnAmount) {
        this.forwardAmount = forwardAmount;
        this.turnAmount = turnAmount;
    }

    public void ClearTurnSpeed() {
        turnSpeed = 0f;
    }

    public float GetSpeed() {
        return speed;
    }


    public void SetSpeedMax(float speedMax) {
        this.speedMax = speedMax;
    }

    public void SetTurnSpeedMax(float turnSpeedMax) {
        this.turnSpeedMax = turnSpeedMax;
    }

    public void SetTurnSpeedAcceleration(float turnSpeedAcceleration) {
        this.turnSpeedAcceleration = turnSpeedAcceleration;
    }

    public void StopCompletely() {
        speed = 0f;
        turnSpeed = 0f;
    }

}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;และใน version ที่พึ่งได้เล่นไป จะเป็น  version แรกที่รถ จะสามารถ ขับได้โดยผู้เล่นผ่านโค้ดของ&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class CarAi : MonoBehaviour
{
    [SerializeField] private Transform targetPositionTranform;
    private CarDriver CarDriver;
    private Vector3 TargetPosition;
    // Start is called before the first frame update
    private void Awake()
    {
        CarDriver = GetComponent&amp;lt;CarDriver&amp;gt;();
    }

    // Update is called once per frame
    void Update()
    {
        SetTargetPosition(targetPositionTranform.position);
        float forwardAmount = 0;
        float turnAmount = 0f;

        float reachTargetDistance = 7f;
        float distanceToTarget = Vector3.Distance(transform.position, TargetPosition);
        if(distanceToTarget &amp;gt; reachTargetDistance) {
            Vector3 dirToMovePosition = (TargetPosition - transform.position).normalized;
            float dot = Vector3.Dot(transform.forward, dirToMovePosition);

            if (dot &amp;gt; 0)
            {
                forwardAmount = 1f;
            }
            else
            {
                float reversDistance = 25f;
                if(distanceToTarget &amp;gt; reversDistance)
                {
                    forwardAmount = 1f;
                }
                else
                {
                    forwardAmount = -1f;
                }

            }

            float angleToDir = Vector3.SignedAngle(transform.forward, dirToMovePosition, Vector3.up);
            if (angleToDir &amp;gt; 0)
            {
                turnAmount = 1f;
            }
            else
            {
                turnAmount = -1f;
            }
        }
        else
        {
            if(CarDriver.GetSpeed() &amp;gt; 15f)
            {
                forwardAmount = -1f;
            }
            else
            {
                forwardAmount = 0f;
            }

            turnAmount = 0f;
        }

        CarDriver.SetInputs(forwardAmount, turnAmount);
    }
    public void SetTargetPosition(Vector3 TargetPosition)
    {
        this.TargetPosition = TargetPosition;
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;นำไปใส้เป็น component ของรถให้สามารถขับได้&lt;/p&gt;

&lt;p&gt;จากนั้นเครื่องมือต่อไปที่ใช้ คือ asset ML-agent ที่เป็น  asset ที่สามารถสร้าง agent ซึ่งจะเป็น component ของ ai ที่เราต้องการผ่าน GitHub &lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--A9-wwsHG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/Unity-Technologies"&gt;
        Unity-Technologies
      &lt;/a&gt; / &lt;a href="https://github.com/Unity-Technologies/ml-agents"&gt;
        ml-agents
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      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 learning and imitation learning.
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;Unity ML-Agents Toolkit&lt;/h1&gt;
&lt;/div&gt;

&lt;p&gt;&lt;a href="https://github.com/Unity-Technologies/ml-agents/tree/release_21_docs/docs/"&gt;&lt;img src="https://camo.githubusercontent.com/7cc04c0a8eb0aa147cdd500be40a4274aef7ab8ad923609ae2c6522d1cae1a23/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f646f63732d7265666572656e63652d626c75652e737667" alt="docs badge"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/Unity-Technologies/ml-agents../LICENSE.md"&gt;&lt;img src="https://camo.githubusercontent.com/336cf44c90c3018c78147c01ada6f5c7df315065322173b9a3445403facf1f83/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f6c6963656e73652d4170616368652d2d322e302d677265656e2e737667" alt="license badge"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;(&lt;a href="https://github.com/Unity-Technologies/ml-agents/releases/tag/latest_release"&gt;latest release&lt;/a&gt;)
(&lt;a href="https://github.com/Unity-Technologies/ml-agents/releases"&gt;all releases&lt;/a&gt;)&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The Unity Machine Learning Agents Toolkit&lt;/strong&gt; (ML-Agents) is an open-source
project that enables games and simulations to serve as environments for
training intelligent agents. We provide implementations (based on PyTorch)
of state-of-the-art algorithms to enable game developers and hobbyists to easily
train intelligent agents for 2D, 3D and VR/AR games. Researchers can also use the
provided simple-to-use Python API to train Agents using reinforcement learning
imitation learning, neuroevolution, or any other methods. These trained agents can be
used for multiple purposes, including controlling NPC behavior (in a variety of
settings such as multi-agent and adversarial), automated testing of game builds
and evaluating different game design decisions pre-release. The ML-Agents
Toolkit is mutually beneficial for both game developers and AI researchers as it
provides a central platform where advances in AI can be evaluated on Unity’s
rich environments and then…&lt;/p&gt;
&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/Unity-Technologies/ml-agents"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;


&lt;p&gt;เมือทำการ install เสร็จแล้วจึงสามารถใช้  ML-agents Component ได้&lt;/p&gt;

&lt;h2&gt;
  
  
  โดยตัว Ai จะมีการทำ Reinforcement learning
&lt;/h2&gt;

&lt;p&gt;โดยจะมีรำดับการทำงานที่&lt;/p&gt;

&lt;p&gt;1.Observation&lt;br&gt;
 ทำการสังเกตุ enivromentในเกมเพื่อเก็บข้อมูลประกอบการทำงานในขั้นต่อไป&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public override void CollectObservations(VectorSensor sensor)(
       sensor.AddObervation(transform.position);//ให้ ai สั่งเกตุตำแหน่งของตัวรถ
       sensor.AddObervation(target.Transform.position);//ให้ ai สังเกตุตำแหน่งของเป้าหมาย
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;2.Decision &lt;br&gt;
 การตัดสินใจจากองค์ประกอบต้างๆที่ได้เก็บข้อมูลมา&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public override void OnActionReceived(ActionBuffers action){
      float moveX = action.ContinuousActions[0];
      float moveZ = action.ContinuousActions[1];// ให้aiทำการเคลื่อนที่เข้าหาเป้าหมายมากขึ้น 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;3.Reward&lt;br&gt;
 รับรางวัลเพื่อพิสูจว่าสิ่งที่ Ai ทำไปนั้นเป็นสิ่งที่ถูกต้องตามที่กำหนดไว้ซึ่งหากผิดจะต้องกับไปที่กระบวนการเเรกไหม่ทั้งหมด&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; private void OnTriggerEnter(Collider other){
              SetReward(1f); // เมื่อรถชนวัตถุที่เราต้องการแล้วจึงจะได้รางวัล
              EndEpisode(); 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;เมือทำการCode สำเร็จ รถจะสามารถขับได้ด้วยตัวเอง&amp;gt;-&amp;lt;&lt;/p&gt;

</description>
      <category>python</category>
      <category>unity3d</category>
      <category>gamedev</category>
    </item>
  </channel>
</rss>
