Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 12 Next capture
2021 2022 2023
1 capture
12 Jun 22 - 12 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
1
Question by vsemenyakin · Mar 10, 2019 at 10:18 PM · rigidbody2dphysics2dsimulation

What is the best way to implement physic simulation prediction for AI in Unity?

I develop top-down 2d cars battle game. Cars has rather complex physics, with simulation of each wheel direct and side resistances, smooth contoled gas and steering wheels rotation. Additionaly, physics may be changed for game design purposes.... And, yeap, now I need to write AI for cars control.
.
To predicate car physics behaviour for low level AI (low level means simple actions control, like orienting to target rotation), I tried to find precise solution of car movement differential equation. But, unfortunately, it looks like my math skills are not so perfect to do it.
Currently I see next acceptable options: use some kind of heuristic algorithm (genetic algorithms, deep learing and so on) or just simulate several variants of car control in next frames and select the most suitable.
.
My expirience in heuristic algorithm is limited university studies, so I decided to use simulation (furthermore, simulation will be needed for heuristic algorithm too). And, finally, my question... What is the best way to create very simple physics scene separated from main scene that will be used only for simple simulation of rigid bodies future behviour for AI? Each AI will use body on this scene to setup this AI's car physic state, perform a few dozens of simulation steps and decide what control variant is the best to achieve needed state.
.
I found Separating Physics Scenes topic on Unity forum and thought that this is what I need. But then I read SceneManager.CreateScene documation and next sentence made me doubt: "The new Scene will be opened additively into the hierarchy alongside any existing Scenes that are currently open". Will be the physics of new scene separated from game scene? Or there is some more correct way to achieve needed result?
.
Sorry about so lot of words... But I think this topic will be interesting not only for me. A lot of games using physic-based gameplay and most of them need AI for game units.
.
P.S.: I know, that there is simple solution - use simplified physics for drived by AI cars. I'll leave this option as a last solution if all other will be too complex for me.
.
UPDATE: I have just found forum topic ("Physics simulate for a single object possible") that seems confirming usage Separating Physics Scenes as solution of my task. I leave this question opened until testing and will publish result as answer (unless a more suitable solution appears).

Comment
Add comment · Show 2
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image Captain_Pineapple · Mar 10, 2019 at 09:27 PM 0
Share

Hey there,

tough topic you got there, not sure if you will get a decent answer for this. From my experience with ai behaviour i think your approach is a bit over the top high-techy. Sounds nice but for a setup that i encountered i simply used 2 raycasts and the relative player position to steer vehicles in 3d.(They have their issues -> do not recognize cliffs and will flip from time to time but that did not matter for me) That was enough to make it look nice. Players most likely will never notice any ultra sophisticated ai behavior (well except for the case that this is the main core of your game) So to keep it short: Try to keep it as simple as possible. Also makes debugging far easier. Hope this helps you on anyways...

avatar image vsemenyakin Captain_Pineapple · Mar 17, 2019 at 09:45 AM 0
Share

Sorry, forgot to answer... Thank you for advice, but, unfortunately, it's impossible to select such simple solution in my case. Firstly, I have no track limited by walls. Secondly, AI should follow some moving object (for example, player's car), not just move through the track avoiding walls and other obstacles. When implementing pursuit for object with complex physics, microtasks that looks simple (like "rotate until you are not looking to pursuited object") transforms to complex one. Simulation make possible to test a number of standard maneuvers and select next AI action based on the most suitable simulation result.

1 Reply

· Add your reply
  • Sort: 
avatar image
2
Best Answer

Answer by vsemenyakin · Mar 17, 2019 at 08:49 AM

Finally, I can answer for my question) I created two small code examples of using 2d physics simulation.
.
Repo link
.
In first example we create separated scene with 2d physics, create GameObject with collider+rigid body on active (main/default) scene, move this object to created simulation scene, launch this object by starting force and perform 50 physics steps of gravity simulation drawing the result of each step. This example is extrimly simple and, I think, should be simple to understand without other explenation.
.

 using UnityEngine;
 using UnityEngine.SceneManagement;
 
 public class VerySimpleSimulationTest : MonoBehaviour
 {
     void Start() {
         performSimpleFlyingInGravityTest();
     }
 
     void performSimpleFlyingInGravityTest()
     {
         //Create simulation scene
         Scene theScene = SceneManager.CreateScene(
             "PhysicsSimulation", /*Scene name*/
             new CreateSceneParameters(LocalPhysicsMode.Physics2D) /*Type of physics on scene*/
         );
         PhysicsScene2D thePhysicsScene = theScene.GetPhysicsScene2D();
 
         //Create object that will be simulated
         GameObject theGameObject = new GameObject();
         var theCollider = theGameObject.AddComponent<BoxCollider2D>();
         var theRigidBody = theGameObject.AddComponent<Rigidbody2D>();
 
         //Object is created in scene that is currently active.
         // So we should move object to simulation scene using
         // SceneManager.MoveGameObjectToScene(...) or
         // set simulation scene as active using
         // SceneManager.SetActiveScene(...)
         SceneManager.MoveGameObjectToScene(theGameObject, theScene);
 
         //Perform simulation
         //-Give starting force
         theRigidBody.AddForce(new Vector2(200.0f, 500.0f));
 
         for (int theStepIndex = 0; theStepIndex < 50; ++theStepIndex)
         {
             //-Apply gravity (instead of default created physics
             //- we need to apply it manually)
             theRigidBody.AddForce(new Vector2(0.0f, -9.8f));
 
             //-Draw current object position in simulation
             drawSquare(theGameObject.transform.position, theCollider.size, Color.green, 10.0f);
 
             //-Perform scene simulation step with delta time 0.02 seconds
             thePhysicsScene.Simulate(0.02f);
         }
     }
 
     static void drawSquare(Vector2 inPosition, Vector2 inSize, Color inColor, float inDuration) {
         Vector2 theRectCornerPosition = inPosition;
         theRectCornerPosition -= inSize/2;
 
         Vector2 theLastRectCornerPosition = theRectCornerPosition;
         theRectCornerPosition.x += inSize.x;
         Debug.DrawLine(theLastRectCornerPosition, theRectCornerPosition, inColor, inDuration, false);
 
         theLastRectCornerPosition = theRectCornerPosition;
         theRectCornerPosition.y += inSize.y;
         Debug.DrawLine(theLastRectCornerPosition, theRectCornerPosition, inColor, inDuration, false);
 
         theLastRectCornerPosition = theRectCornerPosition;
         theRectCornerPosition.x -= inSize.x;
         Debug.DrawLine(theLastRectCornerPosition, theRectCornerPosition, inColor, inDuration, false);
 
         theLastRectCornerPosition = theRectCornerPosition;
         theRectCornerPosition.y -= inSize.y;
         Debug.DrawLine(theLastRectCornerPosition, theRectCornerPosition, inColor, inDuration, false);
     }
 }
 

.
Second example makes approximly the same, but incapsulates simulated object logic to separate class and use implemented API to continue updates in FixedUpdate of main scene. We create separate scipt to hold object simulation specific logic. Pay an attantion how API of the simulated object changes for possibility to perform simulation independtly from any Updates: we create simulateStep() method for simulated object to perform actions that ordinary takes place in FixedUpdate() and call it manualy before all simulated physics scene simulation update.
.

 using UnityEngine;
 
 public class SimulatedObjectLogic : MonoBehaviour
 {
     private BoxCollider2D _collider = null;
     private Rigidbody2D _rigidBody = null;
 
     //API
     public void launch(Vector2 inForce) {
         getRigidbody().AddForce(inForce);
     }
 
     //Method that should be used insted FixedUpdate before simulated scene
     // Simulate(...) call
     public void simulateStep() {
         getRigidbody().AddForce(new Vector2(0.0f, -9.8f));
     }
 
     public void draw() {
         drawSquare(transform.position, getBoxCollider().size, Color.green, 10.0f);
     }
 
     //Implementation details
 
     //NB: As we want to simulate object at start of the test the start
     // of Simulated Object may be called to late. So it's good idea
     // don't save references to components here, but use lazy accessors
     // with caching of component references
     
     //private void Start() {
     //    _collider = gameObject.GetComponent<BoxCollider2D>();
     //    _rigidBody = gameObject.GetComponent<Rigidbody2D>();
     //}
 
     // VS
 
     private BoxCollider2D getBoxCollider() {
         if (null == _collider) _collider = gameObject.GetComponent<BoxCollider2D>();
         return _collider;
     }
 
     private Rigidbody2D getRigidbody() {
         if (null == _rigidBody) _rigidBody = gameObject.GetComponent<Rigidbody2D>();
         return _rigidBody;
     }
 
     //-Utils
     static void drawSquare(Vector2 inPosition, Vector2 inSize, Color inColor, float inDuration)
     {
         Vector2 theRectCornerPosition = inPosition;
         theRectCornerPosition -= inSize / 2;
 
         Vector2 theLastRectCornerPosition = theRectCornerPosition;
         theRectCornerPosition.x += inSize.x;
         Debug.DrawLine(theLastRectCornerPosition, theRectCornerPosition, inColor, inDuration, false);
 
         theLastRectCornerPosition = theRectCornerPosition;
         theRectCornerPosition.y += inSize.y;
         Debug.DrawLine(theLastRectCornerPosition, theRectCornerPosition, inColor, inDuration, false);
 
         theLastRectCornerPosition = theRectCornerPosition;
         theRectCornerPosition.x -= inSize.x;
         Debug.DrawLine(theLastRectCornerPosition, theRectCornerPosition, inColor, inDuration, false);
 
         theLastRectCornerPosition = theRectCornerPosition;
         theRectCornerPosition.y -= inSize.y;
         Debug.DrawLine(theLastRectCornerPosition, theRectCornerPosition, inColor, inDuration, false);
     }
 }
 

.

 using UnityEngine;
 using UnityEngine.SceneManagement;
 
 public class SimpleSimulationTest : MonoBehaviour
 {
     public GameObject ObjectToSimulatePrefab = null;
 
     PhysicsScene2D _physicsScene;
     GameObject _objectToSimulte = null;
 
     void Start() {
         //Create simulation scene
         Scene theScene = SceneManager.CreateScene(
             "PhysicsSimulation",
             new CreateSceneParameters(LocalPhysicsMode.Physics2D)
         );
         _physicsScene = theScene.GetPhysicsScene2D();
 
         //Create object that will be simulated
         _objectToSimulte = GameObject.Instantiate(ObjectToSimulatePrefab);
         SceneManager.MoveGameObjectToScene(_objectToSimulte, theScene);
 
         //Perform starting simulation
         SimulatedObjectLogic theSimulatedObjectLogic =
                 _objectToSimulte.GetComponent<SimulatedObjectLogic>();
 
         theSimulatedObjectLogic.launch(new Vector2(200.0f, 500.0f));
         for (int theStepIndex = 0; theStepIndex < 50; ++theStepIndex)
         {
             theSimulatedObjectLogic.draw();
 
             theSimulatedObjectLogic.simulateStep();
             _physicsScene.Simulate(0.02f);
         }
     }
 
     private void FixedUpdate() {
         //Simulate next steps in main scene FixedUpdate
         SimulatedObjectLogic theSimulatedObjectLogic =
                 _objectToSimulte.GetComponent<SimulatedObjectLogic>();
 
         theSimulatedObjectLogic.draw();
 
         theSimulatedObjectLogic.simulateStep();
         _physicsScene.Simulate(0.02f);
     }
 }

.
P.S.: I have not a lot of experience in Unity - so may update this answer after discovering new details.

Comment
Add comment · Show 1 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image Captain_Pineapple · Mar 16, 2019 at 09:28 PM 0
Share

thx for sharing your solution!

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

105 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

Dynamic colliders without Rigidbodies? 0 Answers

Maintaining the trajectory of a ball when manipulating its velocity in a Breakout/Arkanoid clone 1 Answer

Prevent reseting of GameObject physics state on SceneManager.MoveGameObjectToScene(...) 0 Answers

Rigidbody2D doesn't move 0 Answers

Move an object via Rigidbody2D Physics and Transform at same time 0 Answers


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges