Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 13 Next capture
2021 2022 2023
1 capture
13 Jun 22 - 13 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 therobbyjj · Jul 12, 2021 at 07:16 PM · physicslightspace shooter

How would one model speed of light propagation in unity for a space combat sim?

I'm working on a space combat sim that takes place over relatively vast areas (a cube of space ~20 light minutes to a side) and uses (mostly) realistic physics. One of the key elements I want to model is the propagation speed of information across the battle space -- that is, if Player A engages his main drive on one side of the battle space, there's a 20 minute delay before Player B sees it and can react to it

Even for relatively small battle spaces this is an important factor given the speeds involved. A 500m long ship doing 30kps is going to displace itself by its full length in 1/60th of a second, so even targeting an opponent just few tenths of a light second away are going to be affected by light lag.

I've not seen this done before, and I'm wondering if there are some best practices for modeling this.

Similar to the excellent question asked here a few years ago on stack exchange (indeed I have taken his question as it is very well put), which is unresolved: https://gamedev.stackexchange.com/questions/47784/modeling-speed-of-light-information-propagation-in-space-combat-sim

Are there any packages I should be aware of?

One way I had thought of doing it was to say have a sensor pule every x seconds emmited from the user object. And for objects away from the observer to emit a different layer every x seconds, which would become visible to the user when the "light" from the distant object has reached the user and then delete the layers as required. Although I think this would get intensive very quickly and only a few objects could be handled

Comment
Add comment · Show 1
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 datnasty2_0 · Jul 12, 2021 at 08:31 PM 0
Share

I would like to know how to fix this also.

2 Replies

· Add your reply
  • Sort: 
avatar image
1

Answer by andrew-lukasik · Jul 12, 2021 at 11:10 PM

Interesting question.

It strikes me as the easiest way to implement it would be to record transform history for every unit and then let any ship observe position of others by looking back into their history based on distance between them (to calc time delta). It's not accurate but approximates the effect.

white paths - transform history

meshes - real positions

wire boxes - observed positions

note how the observed object position vary and depends on distance:

alt text

Zero optimizations, just a barely working, late-night sketch of an idea.

SpaceShip.cs

 using System.Collections.Generic;
 using UnityEngine;
 
 public class SpaceShip : MonoBehaviour
 {
     const float k_speed_of_light = 1f;// world units per second
     const int k_max_past = 100;// seconds to buffer
     [SerializeField] float _speed = 1f;// world units per second
     static List<SpaceShip> _instances = new List<SpaceShip>();
     RingBuffer<Matrix4x4> _past = new RingBuffer<Matrix4x4>( k_max_past );
 
     Vector3 _destination;
 
     #if UNITY_EDITOR
     void OnDrawGizmos ()
     {
         Vector3 position = transform.position;
         {
             Gizmos.color = Color.HSVToRGB( Mathf.Abs((float)GetHashCode()%17f)/17f , 1 , 1 );
             int numInstances = _instances.Count;
             for( int i=0 ; i<numInstances ; i++ )
             {
                 var other = _instances[i];
                 if( other!=this )
                 {
                     float distance = Vector3.Magnitude( other.transform.position - position );
                     float seconds = distance / k_speed_of_light;
                     var enumerator = other._past.GetEnumeratorBackward();
                     int secondsInt = Mathf.FloorToInt( seconds );
                     for( int step=0 ; step<=secondsInt ; step++ )
                         enumerator.MoveNext();
                     Gizmos.DrawLine( position , enumerator.Current.GetColumn(3) );
                     Gizmos.matrix = enumerator.Current;//Matrix4x4.TRS( pos , enumerator.Current.rotation , Vector3.one );
                     Gizmos.DrawWireCube( Vector3.zero , Vector3.one/2f );
                     Gizmos.matrix = Matrix4x4.identity;
                 }
             }
         }
         {
             var enumerator = _past.GetEnumeratorBackward();
             enumerator.MoveNext();
             int i = 0;
             Vector3 p0 = enumerator.Current.GetColumn(3);
             while( enumerator.MoveNext() )
             {
                 Vector3 p1 = enumerator.Current.GetColumn(3);
                 Gizmos.color = new Color{ r=1 , g=1 , b=1 , a=1f-((float)(i++)/(float)k_max_past) };
                 Gizmos.DrawLine( p0 , p1 );
                 p0 = p1;
             }
         }
     }
     #endif
 
     void OnEnable () => _instances.Add( this );
     void OnDisable () => _instances.Remove( this );
 
     void Start ()
     {
         var ltw = transform.localToWorldMatrix;
         for( int i=_past.Capacity-1 ; i!=-1 ; i-- )
             _past.Push( ltw );
         
         InvokeRepeating( nameof(Tick) , 0f , 1f );
         InvokeRepeating( nameof(RandomDestination) , 0f , 1.77f );
     }
 
     void FixedUpdate ()
     {
         float dt = Time.fixedDeltaTime;
         Vector3 pos = transform.position;
         Vector3 dir = _destination - pos;
         transform.position = Vector3.MoveTowards( pos , _destination , _speed * dt );
         transform.rotation = Quaternion.Lerp( transform.rotation , Quaternion.LookRotation(dir.normalized) , dt );
     }
 
     void Tick () => _past.Push( transform.localToWorldMatrix );
 
     void RandomDestination () => _destination = Random.insideUnitSphere * 10f;
 
 }

RingBuffer.cs

 using System.Collections;
 using System.Collections.Generic;
 [System.Serializable]
 public class RingBuffer <T> : IEnumerable, IEnumerable<T>
 {
 
     readonly T[] _array;
     public readonly int Capacity;
     
     /// <summary> Current index </summary>
     /// <remarks> (not next one) </remarks>
     int _index;
     public int Index => _index;
 
     [System.Obsolete("don't",true)]
     public RingBuffer () {}
     public RingBuffer ( int capacity )
     {
         this._array = new T[ capacity ];
         this.Capacity = capacity;
         this._index = 0;
     }
     
     public void Push ( T value )
     {
         _array[ _index++ ] = value;
         if( _index==Capacity ) _index = 0;
     }
     public T Peek () => _array[_index];
     public T this [ int index ] => _array[index];
 
     IEnumerator IEnumerable.GetEnumerator ()
     {
         for( int i=_index ; i<Capacity ; i++ ) yield return _array[i];
         for( int i=0 ; i<_index ; i++ ) yield return _array[i];
     }
     public IEnumerator<T> GetEnumerator ()
     {
         for( int i=_index ; i<Capacity ; i++ ) yield return _array[i];
         for( int i=0 ; i<_index ; i++ ) yield return _array[i];
     }
     public IEnumerator<T> GetEnumeratorBackward ()
     {
         for( int i=_index ; i!=-1 ; i-- ) yield return _array[i];
         for( int i=Capacity-1 ; i>_index ; i-- ) yield return _array[i];
     }
 
     public T[] AsArray () => _array;
 
 }

Comment
Add comment · 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
0

Answer by JxWolfe · Jul 12, 2021 at 09:24 PM

create an gameobject to represent the ships real positioning. Then the model of the ship goes under it.

Using Vector3.distance() you should be able to figure out how close that ship is to you. You can do a quick calculation of ingame distance to light speed minutes/seconds (NOTICE: unless the player has a lot to do, even a single minute is a lot of time to be uninformed. OR ingame seconds do not equal out of game seconds).

As the gameobject moves, have the model "ghost" the gameobject, following it within a certain amount of time. Example: gameobject moves, turns left, moves. Ship moves seconds more, turns left (20 seconds after gameobject turned), moves (again later). Basically the animation would be set backward a number of seconds. Changing the animation speed to catch up (ships closer to player) or slow down (ships further than player).

This solutions DOES NOT WORK on multiplayer, at least without a server only sending the models through.

Comment
Add comment · 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

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

204 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 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

2D Plane Axis Restriction, Photon Networking & Physics... 0 Answers

Darker blocks as they go deeper in the ground (2D Game) 0 Answers

(Light enabled colliders) given a surface, how to make a collider such that only the portions of the surface in contact with a light source are activated?(Game example included) 0 Answers

2D 360 degress platformer example needed 0 Answers

AddForce has no effect on my cannonball. 3 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