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
0
Question by Cesurix · Jun 21, 2021 at 06:45 PM · multiplayerphotonpun

Accesing the position of a prefab (Photon Prefab)

Hello everyone, Im trying to make a online multiplayer game with photon networking and i have the player prefab. But at the same time im trying to make infinte, procedural world generation. In order to do that i need to get the transform of the player. But it is a prefab and i can't get the transform of the player. Please help me. Kind Regards, Cesurix Here is my code:

 using System.Collections;
  using System.Collections.Generic;
  using System.Linq;
  using UnityEngine;
  
  public class TerrainController : MonoBehaviour {
  
      [SerializeField]
      private GameObject terrainTilePrefab = null;
      [SerializeField]
      private Vector3 terrainSize = new Vector3(20, 1, 20);
      public Vector3 TerrainSize { get { return terrainSize; } }
      [SerializeField]
      private Gradient gradient;
      [SerializeField]
      private float noiseScale = 3, cellSize = 1;
      [SerializeField]
      private int radiusToRender = 5;
      [SerializeField]
      private Transform[] gameTransforms;
      [SerializeField]
      private Transform playerTransform;
      [SerializeField]
      private Transform water;
      [SerializeField]
      private float uvScale = 1;
  
      public Transform Water { get { return water; } }
      [SerializeField]
      private int seed;
      [SerializeField]
      private GameObject[] placeableObjects;
      public GameObject[] PlaceableObjects { get { return placeableObjects; } }
      [SerializeField]
      private Vector3[] placeableObjectSizes;//the sizes of placeableObjects, in matching order
      public Vector3[] PlaceableObjectSizes { get { return placeableObjectSizes; } }
      [SerializeField]
      private int minObjectsPerTile = 0, maxObjectsPerTile = 20;
      public int MinObjectsPerTile { get { return minObjectsPerTile; } }
      public int MaxObjectsPerTile { get { return maxObjectsPerTile; } }
      [SerializeField]
      private float destroyDistance = 1000;
      [SerializeField]
      private bool usePerlinNoise = true;
      [SerializeField]
      private Texture2D noise;
      public static float[][] noisePixels;
  
      private Vector2 startOffset;
  
      private Dictionary<Vector2, GameObject> terrainTiles = new Dictionary<Vector2, GameObject>();
  
      private Vector2[] previousCenterTiles;
      private List<GameObject> previousTileObjects = new List<GameObject>();
      public Transform Level { get; set; }
      private Vector2 noiseRange;
  
      private void Awake() {
          if (noise)
              noisePixels = GetGrayScalePixels(noise);
          GenerateMesh.UsePerlinNoise = usePerlinNoise;
          noiseRange = usePerlinNoise ? Vector2.one * 256 : new Vector2(noisePixels.Length, noisePixels[0].Length);
      }
  
      private void Start() {
          InitialLoad();
      }
  
      public void InitialLoad() {
          DestroyTerrain();
  
          Level = new GameObject("Level").transform;
          water.parent = Level;
          playerTransform.parent = Level;
          foreach (Transform t in gameTransforms)
              t.parent = Level;
  
          float waterSideLength = radiusToRender * 2 + 1;
          water.localScale = new Vector3(terrainSize.x / 10 * waterSideLength, 1, terrainSize.z / 10 * waterSideLength);
  
          Random.InitState(seed);
          //choose a random place on perlin noise
          startOffset = new Vector2(Random.Range(0f, noiseRange.x), Random.Range(0f, noiseRange.y));
          RandomizeInitState();
      }
  
      private void Update() {
          //save the tile the player is on
          Vector2 playerTile = TileFromPosition(playerTransform.localPosition);
          //save the tiles of all tracked objects in gameTransforms (including the player)
          List<Vector2> centerTiles = new List<Vector2>();
          centerTiles.Add(playerTile);
          foreach (Transform t in gameTransforms)
              centerTiles.Add(TileFromPosition(t.localPosition));
  
          //if no tiles exist yet or tiles should change
          if (previousCenterTiles == null || HaveTilesChanged(centerTiles)) {
              List<GameObject> tileObjects = new List<GameObject>();
              //activate new tiles
              foreach (Vector2 tile in centerTiles) {
                  bool isPlayerTile = tile == playerTile;
                  int radius = isPlayerTile ? radiusToRender : 1;
                  for (int i = -radius; i <= radius; i++)
                      for (int j = -radius; j <= radius; j++)
                          ActivateOrCreateTile((int)tile.x + i, (int)tile.y + j, tileObjects);
                  if (isPlayerTile)
                      water.localPosition = new Vector3(tile.x * terrainSize.x, water.localPosition.y, tile.y * terrainSize.z);
              }
              //deactivate old tiles
              foreach (GameObject g in previousTileObjects)
                  if (!tileObjects.Contains(g))
                      g.SetActive(false);
  
              //destroy inactive tiles if they're too far away
              List<Vector2> keysToRemove = new List<Vector2>();//can't remove item when inside a foreach loop
              foreach (KeyValuePair<Vector2, GameObject> kv in terrainTiles) {
                  if (Vector3.Distance(playerTransform.position, kv.Value.transform.position) > destroyDistance && !kv.Value.activeSelf) {
                      keysToRemove.Add(kv.Key);
                      Destroy(kv.Value);
                  }
              }
              foreach (Vector2 key in keysToRemove)
                  terrainTiles.Remove(key);
  
              previousTileObjects = new List<GameObject>(tileObjects);
          }
  
          previousCenterTiles = centerTiles.ToArray();
      }
  
      //Helper methods below
  
      private void ActivateOrCreateTile(int xIndex, int yIndex, List<GameObject> tileObjects) {
          if (!terrainTiles.ContainsKey(new Vector2(xIndex, yIndex))) {
              tileObjects.Add(CreateTile(xIndex, yIndex));
          } else {
              GameObject t = terrainTiles[new Vector2(xIndex, yIndex)];
              tileObjects.Add(t);
              if (!t.activeSelf)
                  t.SetActive(true);
          }
      }
  
      private GameObject CreateTile(int xIndex, int yIndex) {
          GameObject terrain = Instantiate(
              terrainTilePrefab,
              Vector3.zero,
              Quaternion.identity,
              Level
          );
          //had to move outside of instantiate because it's a local position
          terrain.transform.localPosition = new Vector3(terrainSize.x * xIndex, terrainSize.y, terrainSize.z * yIndex);
          terrain.name = TrimEnd(terrain.name, "(Clone)") + " [" + xIndex + " , " + yIndex + "]";
  
          terrainTiles.Add(new Vector2(xIndex, yIndex), terrain);
  
          GenerateMesh gm = terrain.GetComponent<GenerateMesh>();
          gm.TerrainSize = terrainSize;
          gm.Gradient = gradient;
          gm.NoiseScale = noiseScale;
          gm.CellSize = cellSize;
          gm.UVScale = uvScale;
          gm.NoiseOffset = NoiseOffset(xIndex, yIndex);
          gm.Generate();
  
          Random.InitState((int)(seed + (long)xIndex * 100 + yIndex));//so it doesn't form a (noticable) pattern of similar tiles
          PlaceObjects po = gm.GetComponent<PlaceObjects>();
          po.TerrainController = this;
          po.Place();
          RandomizeInitState();
  
          return terrain;
      }
  
      private Vector2 NoiseOffset(int xIndex, int yIndex) {
          Vector2 noiseOffset = new Vector2(
              (xIndex * noiseScale + startOffset.x) % noiseRange.x,
              (yIndex * noiseScale + startOffset.y) % noiseRange.y
          );
          //account for negatives (ex. -1 % 256 = -1, needs to loop around to 255)
          if (noiseOffset.x < 0)
              noiseOffset = new Vector2(noiseOffset.x + noiseRange.x, noiseOffset.y);
          if (noiseOffset.y < 0)
              noiseOffset = new Vector2(noiseOffset.x, noiseOffset.y + noiseRange.y);
          return noiseOffset;
      }
  
      private Vector2 TileFromPosition(Vector3 position) {
          return new Vector2(Mathf.FloorToInt(position.x / terrainSize.x + .5f), Mathf.FloorToInt(position.z / terrainSize.z + .5f));
      }
  
      private void RandomizeInitState() {
          Random.InitState((int)System.DateTime.UtcNow.Ticks);//casting a long to an int "loops" it (like modulo)
      }
  
      private bool HaveTilesChanged(List<Vector2> centerTiles) {
          if (previousCenterTiles.Length != centerTiles.Count)
              return true;
          for (int i = 0; i < previousCenterTiles.Length; i++)
              if (previousCenterTiles[i] != centerTiles[i])
                  return true;
          return false;
      }
  
      public void DestroyTerrain() {
          water.parent = null;
          playerTransform.parent = null;
          foreach (Transform t in gameTransforms)
              t.parent = Level;
          Destroy(Level);
          terrainTiles.Clear();
      }
  
      private static string TrimEnd(string str, string end) {
          if (str.EndsWith(end))
              return str.Substring(0, str.LastIndexOf(end));
          return str;
      }
  
      public static float[][] GetGrayScalePixels(Texture2D texture2D) {
          List<float> grayscale = texture2D.GetPixels().Select(c => c.grayscale).ToList();
  
          List<List<float>> grayscale2d = new List<List<float>>();
          for (int i = 0; i < grayscale.Count; i += texture2D.width)
              grayscale2d.Add(grayscale.GetRange(i, texture2D.width));
  
          return grayscale2d.Select(a => a.ToArray()).ToArray();
      }
  
  }
Comment
Add comment
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

1 Reply

· Add your reply
  • Sort: 
avatar image
0

Answer by GetLitGames · Jun 20, 2021 at 03:22 PM

remove the InitialLoad() call from your Start()

then add this to your Update()

 private void Update() {
 if (!playerTransform)
 {
     playerTransform = GameObject.FindWithTag("Player");
     if (playerTransform)
         InitialUpdate();
 
     if (!playerTransform)
         return;
 }

... then the rest of your Update code.

Basically this will wait until the player is in the scene to start it's processing, you can use this trick any time you have something that is waiting on something else. This assumes your Player is never destroyed otherwise the InitialPlayer would be called more than once. If you allow the local player to get destroyed then you will want to add a boolean and set it, so you also check something like if (playerTransform && !doneInitialLoad). Also, the you will need to change the Tags on the non-local players to be something else like RemotePlayer at the point that non-local player are spawned in via Photon.

Comment
Add comment · Show 3 · 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 Cesurix · Jun 21, 2021 at 07:15 AM 0
Share

I tried to put your code to the update but it says that GameObject can not be a transform.

avatar image GetLitGames Cesurix · Jun 21, 2021 at 08:37 PM 0
Share

then the one line should be GameObject.FindWithTag("Player").transform instead. You probably need more time to learn more about C# and Unity but I hope that I helped. Keep at it and you will learn.

avatar image Cesurix GetLitGames · Jun 22, 2021 at 06:12 AM 0
Share

Thank you very much that worked just like a charm. I can't find a proper way to thank you. You just saved my life(probably 10 days from my life) THANK YOU :)

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

207 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 avatar image avatar image avatar image

Related Questions

Photon Pun 2 "using photon.pun" not working. 8 Answers

[PHOTON PUN] Players cant shoot each other? 1 Answer

How do I set up multiplayer? 0 Answers

Join Error photon 0 Answers

Photon realtime gameplay and screen local player 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