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 slimabob · Jan 06, 2016 at 09:23 AM · c#networkingraycastmultiplayerraycasting

[C#] UNET Client raycast not the same as Server raycast

I'm trying to fire a ray and then spawn an object at that location. It works perfectly fine on the server, but on any clients the placement is offset and I can't figure out why for the life of me. Here's a picture to describe what I mean in more detail.

alt text

And here's my code:

 using UnityEngine;
 using UnityEngine.Networking;
 using System.Collections;
 
 public class Building_MP : NetworkBehaviour {
 
     [SerializeField]
     GameObject GhostGO;
     [SerializeField]
     LayerMask LM;
 
     bool snap = false;
 
     int ghostID;
 
     // Use this for initialization
     void Start () {
         ghostID = Random.Range(0, 10000);
     }
     
     // Update is called once per frame
     void Update () {
     
         if(Input.GetButtonDown("Fire2") && isLocalPlayer)
         {
             CmdSpawnGhostBrick();
         }
 
         if(isLocalPlayer)
         {
             //CmdMoveGhostBrick();
 
             if (Input.GetKeyDown(KeyCode.B))
             {
                 snap = !snap;
             }
         }
 
     }
 
     [Command]
     void CmdSpawnGhostBrick()
     {
         RaycastHit hit;
         Ray ray = GetComponentInChildren<Camera>().ScreenPointToRay(Input.mousePosition);
         if (Physics.Raycast(ray, out hit, 200.0f, LM))
         {
             GameObject ghostBrick = Instantiate(GhostGO, new Vector3(RoundToHalf(hit.point.x), RoundToHalf(hit.point.y), RoundToHalf(hit.point.z)), Quaternion.identity) as GameObject;
             ghostBrick.transform.name = "GhostBrick (" + ghostID + ")";
             ghostBrick.transform.tag = "Ghost";
             ghostBrick.layer = 10;
             NetworkServer.Spawn(ghostBrick);
             Debug.Log("Hit at " + hit.point.ToString());
             Debug.Log("BrickPos " + ghostBrick.transform.position);
         }
     }
 
     [Command]
     void CmdMoveGhostBrick()
     {
         GameObject ghostBrick = GameObject.Find("GhostBrick (" + ghostID + ")");
         if(ghostBrick != null)
         {
             RaycastHit hit;
             Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
             if (Physics.Raycast(ray, out hit, 100.0f, LM))
             {
                 if (!snap)
                 {
                     ghostBrick.transform.position = new Vector3(RoundToHalf(hit.point.x), RoundToHalf(hit.point.y) + ghostBrick.GetComponent<Renderer>().bounds.size.y / 2, RoundToHalf(hit.point.z));
                 }
                 else
                 {
                     ghostBrick.transform.position = new Vector3(hit.transform.position.x, hit.transform.position.y + ghostBrick.GetComponent<Renderer>().bounds.size.y, hit.transform.position.z);
                 }
             }
 
             if(Input.GetButtonDown("Fire1"))
             {
                 GameObject newBrick = Instantiate(GhostGO, ghostBrick.transform.position, ghostBrick.transform.rotation) as GameObject;
                 NetworkServer.Spawn(newBrick);
             }
         }
     }
 
     [Command]
     void CmdDestroyGhost()
     {
         GameObject ghostBrick = GameObject.Find("GhostBrick (" + ghostID + ")");
         if(ghostBrick != null)
         {
             NetworkServer.Destroy(ghostBrick);
         }
     }
 
     public static float RoundToHalf(float f)
     {
         return f = Mathf.Round(f * 4f) * 0.25f;
     }
 }
 

Thanks a ton in advance, I'm at my wit's end right now.

placement.png (497.0 kB)
Comment
Add comment · Show 7
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 slimabob · Jan 06, 2016 at 06:39 PM 0
Share

Something I forgot to note is that Cmd$$anonymous$$oveGhostBrick is irrelevant to the problem, since I commented it out. All that's being used right now is CmdSpawnGhostBrick. Just figured I'd save anyone whose reading it the extra confusion

avatar image seanr · Jan 06, 2016 at 06:41 PM 0
Share

does the brick have a NetworkTransform?

avatar image slimabob seanr · Jan 06, 2016 at 06:44 PM 0
Share

Yes, it has a networktransform. When the client places a brick, it does place it on the server as well, it's just offset from where the player was looking for whatever reason. This inaccuracy happens when any client tries to place a brick, but not when the server does.

avatar image seanr slimabob · Jan 06, 2016 at 07:17 PM 0
Share

is snap set on both client & server?

Show more comments
avatar image ThaiCat · Jan 06, 2016 at 07:27 PM 0
Share

I would used raycast results i wanted, passing them throgh Cmd/Rpc. In this case it would not matter if they are different on server and clients. I did not paid attention to your code btw.

avatar image slimabob ThaiCat · Jan 06, 2016 at 07:31 PM 0
Share

Could you post an example of this? I'm not 100% positive what you mean.

2 Replies

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

Answer by ThaiCat · Jan 06, 2016 at 08:17 PM

I used this to destroy specific block, that was result of raycast on client. It is not 100% server-authoritative unfortunately, but it is okay for me. You can also send to server additional parameters as hit.point (vector3) or something like that. Note there is network Identity component on that block also.

 void DeleteOnMouseDown()
 {
     //can only destroy components with myParent script attached to them
     if (Input.GetAxis("Fire3") > 0f)
     {
         ray = Camera.main.ScreenPointToRay(Input.mousePosition);
         if (Physics.Raycast(ray, out hit))
         {
             if (hit.collider != null)
             {
                 nearbyColliderParentScript = GetBlockByColliderHit(hit).GetComponent<MyParent>();
                 
                 if (nearbyColliderParentScript != null)
                 {
                     blockToDestroy = nearbyColliderParentScript.myParent.gameObject;        
                     if (blockToDestroy.GetComponent<MountPoints>().markedForDestroy == false)
                     {
                         CmdMarkBlockForDestruction(blockToDestroy);
                         blockToDestroy.GetComponent<MountPoints>().markedForDestroy = true;
                     }
                 }
             }
         }
     }
 }

 [Command]
 void CmdMarkBlockForDestruction(GameObject block)
 {        
     GameObject shipRoot = block.GetComponent<MountPoints>().rootFragment.gameObject;
     shipRoot.GetComponent<ShipIntegrity>().AddBlockToDestroy(block);
 }

Comment
Add comment · Show 4 · 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 slimabob · Jan 06, 2016 at 08:50 PM 0
Share

I noticed that you weren't running the raycast on the server (the [command]), is there any particular reason to not do this?

avatar image ThaiCat slimabob · Jan 06, 2016 at 09:16 PM 1
Share

After i did raycast on client, i know the object on which i want to perfom actions. I send that object to server and server does whatever i want. I see no reason why i should to perform raycast twice.

I dont think it is even possible to make raycast results on every client and server the same in fully dinamic environment (this is my case). But if your scene has static objects, you can still get the same results for them, if you sync camera position&rotation and cursor position right before that.

avatar image slimabob ThaiCat · Jan 06, 2016 at 09:20 PM 0
Share

I think that may be part of my problem then, I'm perfor$$anonymous$$g the raycast on the server. When I get back to my computer I'll give it a shot

avatar image slimabob · Jan 07, 2016 at 08:24 AM 0
Share

Yep, as soon as I moved the raycast from being done on the server to being done on the client and then passed to the server, everything worked fine- thanks!

avatar image
0

Answer by maracepoc · Dec 06, 2017 at 12:58 PM

Hi, Following your discussion on Ray casting I have a related problem. Maybe it's a question that @slimabob could answer: how did you pass the raycast hit collider position to the server as mentioned in your last answer? I'd really appreciate your help. Thank you.

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

5 People are following this question.

avatar image avatar image avatar image avatar image avatar image

Related Questions

Unity networking tutorial? 6 Answers

UNET Health isn't syncing 1 Answer

Multiplayer desynchronize when grabbing an object by code. 0 Answers

(C#) Collider to collider2d 0 Answers

raycasting without colliders 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