• 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
0
Question by sebeisdrache · Jan 22, 2015 at 03:41 PM · multiplayerspacefloatingorigin

Floating Origin and Multiplayer

Hello, I tested this script for a Floating Origin http://wiki.unity3d.com/index.php?title=Floating_Origin to prevent problem with huge Distances.

But If a player reaches the threshold I got strange behavior of the Player SpaceShips.

The enviroment moves correctly but the ship of the other player is not moved with the enviroment, it is still at the relative position to the map origin.

The same for the other player: The ship of the other player reaches the threshold, and get set back to the map origin.

(sorry for the odd english)

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 $$anonymous$$ · Jul 15, 2015 at 10:13 AM 0
Share

I have the same problem, I don't understand what your doing? your using UFPS right?

avatar image sebeisdrache · Jul 15, 2015 at 01:36 PM 0
Share

Waht you mean with UFPS?

2 Replies

· Add your reply
  • Sort: 
avatar image
2

Answer by DaDonik · Jan 24, 2015 at 10:11 PM

Without knowing anything about your multiplayer code, there is not much we can tell you.

I guess the wiki solution you've posted is not really applicable in a multiplayer game, because it only considers the player and it's vicinity. In the case where the other player is not within the threshold, there will be problems.

I'm afraid there is no easy solution to this, but i'm also very interested in space games and therefore i would like to discuss it with you. If you like, you can pm me via the forum and we can talk in our native language.

Comment
Add comment · Show 2 · 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 sebeisdrache · Jan 25, 2015 at 09:43 PM 0
Share

Hello, I think i solved the problem (maybe), I use 2 coordinate systems: One for the "local Space" and another one for the Globalspace, wich is 1:10000 scale.

I Calculate the local position of a Player by using an localoffset variable.

Now there a two problems to solve:

If a player $$anonymous$$oves his/hers local object, the object travels only half the distance it should travel.! [bug?][1] [1]: /storage/temp/39519-bug.jpg

the other Problem is, if I accerlerate to Z+ it works only if the Z+ Velocity is bigger as 0.3 m/s (0.3m/s are calculated by the GlobalRef script)

The player controlls the local Object via Forces in FixedUpdate(). The change velocity is added to the "GlobalSpace" reference Gameobject.

The whole script is a bit to long to post here. Therefore the function that calculates the local Offset (i think there is something wrong, because of the tiny velocity problem and the strange behavior in $$anonymous$$ultiplayer).

     void LocalRef()
     {
         if(localRef != null)
         {
             localDeltaVelocity = localRef.rigidbody.velocity - localVelocity;
             localVelocity = localRef.rigidbody.velocity;
 
             transform.rigidbody.velocity += localDeltaVelocity/Constants.spaceScale;
 
             if(isActive)
             {
                 foreach(SpaceObjectRef otherRef in localSpaceData.localRefs)
                 {
                     if(!otherRef.isActive && otherRef.localRef != null)
                     {
                         otherRef.localOffset = Convert.Vector3dToVector3((otherRef.realPosition - realPosition)*Constants.spaceScale);
                         otherRef.localRef.rigidbody.position = otherRef.localOffset + originOffset;
                     }
                 }
             }
 
         }
         transform.rigidbody.AddForce(Vector3.zero);
     }



 
bug.jpg (67.5 kB)
avatar image DaDonik · Jan 25, 2015 at 11:02 PM 0
Share

I will have a more detailed look at your code tomorrow. From a first glimpse i assume that the value calculated by

 localDeltaVelocity/Constants.spaceScale

might be too small, due to floating point imprecision. This might cause the problem that your velocity has to be bigger than 0.3 m/s.

On a sidenote...don't use foreach if you can work with a simple for loop. Foreach produces garbage, for doesn't.

avatar image
0

Answer by sebeisdrache · Jan 25, 2015 at 09:46 PM

here is my complete Script. I have a Utility and a Constans Class, i think the names should be inform about the ussage (Like gravity constant and set main camera). Vector3d is https://github.com/kohlditz/vector3d

 using UnityEngine;
 using System.Collections;
 
 public class SpaceObjectRef : MonoBehaviour {
 
     public Vector3d realPosition;
     public Vector3d realVelocity;
 
     GameObject localRef;
     public GameObject localRefPrefab;
 
     public bool isActive;
     
     Vector3 localDeltaVelocity;
     Vector3 localVelocity;
 
     public Vector3 localOffset;
 
     Vector3 deltaPosition;
 
     GameObject space;
     GameObject localSpace;
     LocalSpace localSpaceData;
     GameObject skyBoxCam;
     GameObject playerCam;
 
     public double realPositionX;
     public double realPositionY;
     public double realPositionZ;
 
     public double realVelocityX;
     public double realVelocityY;
     public double realVelocityZ;
 
     public double distanceFormPlanet;
     public double distanceFormSurface;
     public double gravityForce;
     public Vector3 directionToPlanet;
     public double speed;
 
     public Planet planet;
 
     Vector3 position;
     public Quaternion rotation;
     public Vector3 angularVelocity;
     Vector3 velocity;
 
     Vector3 originPos;
     Vector3 originOffset;
     
     private float lastSynchronizationTime = 0f;
     private float syncDelay = 0f;
     private float syncTime = 0f;
     private Vector3 syncStartPosition = Vector3.zero;
     private Vector3 syncEndPosition = Vector3.zero;
     private Quaternion syncStartRotation = Quaternion.identity;
     private Quaternion syncEndRotation = Quaternion.identity;
     private bool gotSync = false;
     
     void Awake ()
     {
         GetValues();
         ApplyValues();
 
         localSpace = GameObject.Find("LocalSpace");
 
         skyBoxCam = GameObject.FindGameObjectWithTag("SkyBoxCam");
 
 
         space = GameObject.Find("Space");
         localSpaceData = localSpace.GetComponent<LocalSpace>();
 
 
         if(networkView.isMine)
         {
             isActive = true;
         }
 
         if(transform.parent == null)
         {
             transform.parent = space.transform;
         }
     }
 
     void Start () {
 
         if(isActive && localRefPrefab != null)
         {
             localRef = Instantiate(localRefPrefab, Vector3.zero, rotation) as GameObject;
             localRef.transform.parent = localSpace.transform;
 
             PlayerRef playerRef = localRef.GetComponent<PlayerRef> ();
             if(playerRef != null)
             {
                 playerRef.owner = true;
                 Utility.SetMainCam(playerRef.cam);
             }
             localSpaceData.localRefs.Add(this);
         }
     }
 
     void FixedUpdate()
     {
         if(networkView != null && !networkView.isMine)
         {
             SyncedMovement();
         }
         Gravitiy();
         LocalRef();
         UpdateValues();
     }
 
     void Update()
     {
 
     }
 
     void LateUpdate () {
         skyBoxCam.transform.position = transform.position;
         FloatingOrigin();
     }
 
     void FloatingOrigin()
     {
         if(isActive && localRef != null)
         {
             originPos = localRef.transform.position;
             if(originPos.magnitude > Constants.floatingOriginThreshold)
             {
                 originOffset -= originPos;
                 foreach(Transform child in localSpace.transform)
                 {
                     child.position -= originPos;
                 }
             }
         }
     }
 
     void OnDestroy()
     {
         if(localRef != null)
         {
             Destroy(localRef);
         }
     }
 
     void OnTriggerEnter(Collider other)
     {
         if(isActive)
         {
             SpaceObjectRef spaceObjectRef = other.GetComponent<SpaceObjectRef>();
             localOffset = Convert.Vector3dToVector3((spaceObjectRef.realPosition - realPosition)*Constants.spaceScale);
 
             if(spaceObjectRef.localRefPrefab != null && spaceObjectRef.localRef == null)
             {
                 spaceObjectRef.localRef = Instantiate(spaceObjectRef.localRefPrefab, localOffset, spaceObjectRef.rotation) as GameObject;
                 spaceObjectRef.localRef.rigidbody.angularVelocity = spaceObjectRef.angularVelocity;
                 spaceObjectRef.localRef.transform.parent = localSpace.transform;
 
                 localSpaceData.localRefs.Add(spaceObjectRef);
             }
         }
     }
 
     void OnTriggerExit(Collider other) {
         if(isActive)
         {
             SpaceObjectRef spaceObjectRef = other.GetComponent<SpaceObjectRef>();
             if(spaceObjectRef.localRef != null)
             {
                 Destroy(spaceObjectRef.localRef);
                 localSpaceData.localRefs.Remove(spaceObjectRef);
             }
         }
     }
     
     void LocalRef()
     {
         if(localRef != null)
         {
             localDeltaVelocity = localRef.rigidbody.velocity - localVelocity;
             localVelocity = localRef.rigidbody.velocity;
 
             transform.rigidbody.velocity += localDeltaVelocity/Constants.spaceScale;
 
             if(isActive)
             {
                 foreach(SpaceObjectRef otherRef in localSpaceData.localRefs)
                 {
                     if(!otherRef.isActive && otherRef.localRef != null)
                     {
                         otherRef.localOffset = Convert.Vector3dToVector3((otherRef.realPosition - realPosition)*Constants.spaceScale);
                         otherRef.localRef.rigidbody.position = otherRef.localOffset + originOffset;
                     }
                 }
             }
 
         }
         transform.rigidbody.AddForce(Vector3.zero);
     }
 
     void GetValues()
     {
         if(realPositionX != 0 || realPositionY != 0 || realPositionZ != 0)
         {
             realPosition.x = realPositionX;
             realPosition.y = realPositionY;
             realPosition.z = realPositionZ;
         }
         else
         {
             realPosition = Convert.Vector3ToVector3d(transform.rigidbody.position);
         }
 
         //rotation = transform.rigidbody.rotation;
 
         realVelocity.x = realVelocityX;
         realVelocity.y = realVelocityY;
         realVelocity.z = realVelocityZ;
     }
     
     void ApplyValues()
     {
         position = Convert.Vector3dToVector3(realPosition);
         velocity = Convert.Vector3dToVector3(realVelocity);
 
         transform.rigidbody.position = position;
         //transform.rigidbody.rotation = rotation;
         transform.rigidbody.velocity = velocity;
     }
 
     void UpdateValues()
     {
 
         realPosition = Convert.Vector3ToVector3d(transform.rigidbody.position);
         realVelocity = Convert.Vector3ToVector3d(transform.rigidbody.velocity);
 
         if(localRef != null)
         {
             rotation = localRef.rigidbody.rotation;
             angularVelocity = localRef.rigidbody.angularVelocity;
         }
 
         position = transform.rigidbody.position;
         velocity = transform.rigidbody.velocity;
 
         realPositionX = realPosition.x;
         realPositionY = realPosition.y;
         realPositionZ = realPosition.z;
 
         realVelocityX = realVelocity.x;
         realVelocityY = realVelocity.y;
         realVelocityZ = realVelocity.z;
 
         speed = rigidbody.velocity.magnitude * Constants.spaceScale;
     }
 
     void Gravitiy()
     {
         if(planet != null)
         {
             distanceFormPlanet = Vector3d.Distance(realPosition, planet.realPosition) * Constants.spaceScale;
             distanceFormSurface = distanceFormPlanet -  planet.radius;
 
 
             gravityForce = Constants.gravityConstantD * ( planet.mass / ( distanceFormPlanet * distanceFormPlanet ) );
 
             Vector3d dir = planet.realPosition - realPosition;
             dir.Normalize();
             directionToPlanet = Convert.Vector3dToVector3(dir);
 
             rigidbody.AddForce( directionToPlanet * (float)(gravityForce/Constants.spaceScale), ForceMode.Acceleration);
         }
     }
 
     private void SyncedMovement()
     {
         if(gotSync == true && localRef != null)
         {
             syncTime += Time.deltaTime;
             rigidbody.position = Vector3.Lerp(syncStartPosition, syncEndPosition, syncTime / syncDelay);
             localRef.rigidbody.rotation = Quaternion.Slerp(syncStartRotation, syncEndRotation, syncTime / syncDelay);
         }
     }
     
     void OnSerializeNetworkView(BitStream stream, NetworkMessageInfo info)
     {
         Vector3 syncPosition = Vector3.zero;
         Quaternion syncRotation = Quaternion.identity;
         Vector3 syncVelocity = Vector3.zero;
         
         if (stream.isWriting)
         {
             syncPosition = rigidbody.position;
             stream.Serialize(ref syncPosition);
 
             if(localRef != null)
             {
                 syncRotation = localRef.rigidbody.rotation;
                 stream.Serialize(ref syncRotation);
             }
 
             syncVelocity = rigidbody.velocity;
             stream.Serialize(ref syncVelocity);
         }
         else
         {
             stream.Serialize(ref syncPosition);
             stream.Serialize(ref syncRotation);
             stream.Serialize(ref syncVelocity);
 
             rigidbody.velocity = syncVelocity;
 
             syncTime = 0f;
             syncDelay = Time.time - lastSynchronizationTime;
             lastSynchronizationTime = Time.time;
             
             syncEndPosition = syncPosition + syncVelocity * syncDelay;
             syncStartPosition = rigidbody.position;
 
             if(localRef != null)
             {
                 syncEndRotation = syncRotation;
                 syncStartRotation = localRef.rigidbody.rotation;
             }
             gotSync = true;
         }
     }
 
 }
 
Comment
Add comment · Show 2 · 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 sebeisdrache · Jan 27, 2015 at 02:43 PM 0
Share

I have fixed the Problem with the worng Player Position:

In the update() function I placed: if(isActive) { localRef.transform.positon = Vector3.zero; }

It works in $$anonymous$$ulti and single player and objects can collide with each other. Later I will fixing the Position resolution by using real Orbital mechanics, but i need a bit of knowledge ot it to do it.

avatar image Snownebula sebeisdrache · Aug 23, 2017 at 04:00 PM 0
Share

Did you ever fix this? I was testing your code and I get LocalSpace error thing.

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.

Welcome to Unity Answers

If you’re new to Unity Answers, please check our User Guide to help you navigate through our website and refer to our FAQ for more information.

Before posting, make sure to check out our Knowledge Base for commonly asked Unity questions.

Check our Moderator Guidelines if you’re a new moderator and want to work together in an effort to improve Unity Answers and support our users.

Follow this Question

Answers Answers and Comments

5 People are following this question.

avatar image avatar image avatar image avatar image avatar image

Related Questions

Glitches issues (huge world) 20k x 20k 3 Answers

Exclude Objects From FloatingOrigin 1 Answer

Unity networking tutorial? 6 Answers

Shooting in multiplayer? 0 Answers

Unity3d floating limits? 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