I'm creating multi-play game using photon pun2.
I'm setted the components inherited from the IPunObservable to object contain a photon view.
but, OnPhotonSerializeView is never called.
This code is a function that synchronizes the position and others. but, it didn't work. and it doesn't catch a break point.
This object is created through PhotonNetwork.Instantiate, and here is the contents of the source and prefab.
using Photon.Pun;
using UnityEngine;
public class Character : MonoBehaviourPun, IPunObservable
{
[Header("Properties")]
public float hp;
public float maxHp;
public bool isMoving;
public float moveSpeed;
public Vector2 moveDirection;
private void OnEnable()
{
PhotonNetwork.AddCallbackTarget(this);
}
private void OnDisable()
{
PhotonNetwork.RemoveCallbackTarget(this);
}
/** skip **/
public void OnPhotonSerializeView(PhotonStream stream, PhotonMessageInfo info)
{
Debug.Log(nameof(OnPhotonSerializeView));
if (stream.IsWriting)
{
stream.SendNext(transform.position);
stream.SendNext(hp);
stream.SendNext(maxHp);
stream.SendNext(moveSpeed);
stream.SendNext(isMoving);
stream.SendNext(moveDirection);
}
else if (stream.IsReading)
{
transform.position = (Vector3)stream.ReceiveNext();
hp = (float)stream.ReceiveNext();
maxHp = (float)stream.ReceiveNext();
moveSpeed = (float)stream.ReceiveNext();
isMoving = (bool)stream.ReceiveNext();
moveDirection = (Vector2)stream.ReceiveNext();
}
}
}
Or is there anything I missed about OnPhotonSerializeView?
I understand that it repeats every second as many frames as specified by PhotonNetwork.SerializationRate or PhotonNetwork.SendRate.
sorry about my poor english...
I want to know about is why not OnPhotonSerializeView called or my wrong knowledge about that.
+added
I'm checked that OnPhotonSerializeView called when player entered two or more. but, not.
I'm used PhotonTransformView. but, it's not synchronized transform too.
PunRPC is working normally.
this is skipped source
private void FixedUpdate()
{
if (photonView.IsMine)
{
MoveEvent();
}
}
protected virtual void MoveEvent()
{
isMoving = moveDirection != Vector2.zero;
if (isMoving)
{
transform.position = transform.position + moveDirection * moveSpeed * Time.deltaTime;
}
}
++added
enter image description here
i founded cloned object on other client view. and it's properties are empty. why is this happening?
there is problem on creating room! i will check my room options or typed lobby. Thank you to everyone try to help me.
Related
C# code in image 2:
using System.Collections.Generic;
using UnityEngine;
public class Bossfight : MonoBehaviour
{
public bool triggerboss;
private const float speed = 8.0f;
private Vector2 target = new Vector2(0.0f,3.8f);
public GameObject current;
private void OnTriggerEnter2D(Collider2D collider)
{
if (collider.gameObject.tag == "Player")
{
triggerboss = true;
Debug.Log("Boss Incoming!");
}
}
void Update()
{
if (triggerboss == true)
{
float step = speed * Time.deltaTime;
current.transform.position = Vector2.MoveTowards(transform.position, target, step);
}
}
}
So the triggerboss box is meant to be unticked by default so that when u hit a trigger the boss comes in. But when I hit the trigger the debug for "Boss Incoming!" appears but the boss does not. However, when I tick the triggerboss box, so that its on by default, the boss spawns in immediately along with the debug and I have no idea how both of those things can happen with the same code.
This is also my first project when it comes to making a game btw
This is the error and
I'm using this tutorial
This is my first game in C# and I'm not sure what to do because nobody in the comments said anything about this that I've seen.
This is the exact code that I have wrote.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerMovement : MonoBehaviour
{
public float movementSpeed;
public Rigidbody2D rb;
public float jumpForce = 20f;
public Transform feet;
public LayerMask groundLayers;
float mx;
private void Update()
{
mx = Input.GetAxisRaw("Horizontal");
if (Input.GetButtonDown("Jump") && IsGrounded())
{
Jump();
}
}
private void FixedUpdate()
{
Vector2 movement = new Vector2(mx * movementSpeed, rb.velocity.y);
rb.velocity = movement;
}
void Jump()
{
Vector2 movement = new Vector2(rb.velocity.x, jumpForce);
rb.velocity = movement;
}
public bool IsGrounded()
{
Collider2D groundCheck = Physics2D.OverlapCircle(feet.position, 0.5f, groundLayers);
if (groundCheck != null)
{
return true;
}
return false;
}
}
Thanks in advance, I'm new to C# and its a big help. :)
For detecting the grounded status of the player i would simply use the OnCollisionEnter() method thet you can implement in your script. It detects when any collider attached to your gameobject touches an other. To tell apart the ground from other objects simply use the following:
if(collision.collider.gameobject.comparetag("ground")
{
//if this is true, set a boolean value to indicate that the player is grounded
//and when the player jumps, always set that boolean to false
}
For this to work you have to set the tag for your floor as "ground" (you have to create that yourself).
To jump, i would rather use rg.AddForce(jumpForce, ForceMode.Impulse) as it's cleaner in my opinion.
Also, as a start i would use Keycode.Space in the GetKeyDown() method instead of "Jump" as it gets rid of a variable that you have to check when debugging.
If it still doesn't work, feel free to write a comment here and let me know.
I have been trying to get my prefab as soon as it is instantiated to assign this script but I have looked around a lot and I have only been getting some vague answers this following script is on the prefab:
public float speed;
public float lifeTime;
public float distance;
public ShootingMechanic ShootScript;
public LayerMask whatIsSolid;
private void Start()
{
ShootScript = GameObject.Find("gun").GetComponent<ShootingMechanic>();
Invoke("DestroyProjectile", lifeTime);
}
void DestroyProjectile()
{
//Instantiate(DestroyEffect, transform.position, Quaternion.identity);
Destroy(gameObject);
}
public void Update()
{
transform.Translate(Vector2.up * speed * Time.deltaTime);
RaycastHit2D hitInfo = Physics2D.Raycast(transform.position, transform.up, distance, whatIsSolid);
if(hitInfo.collider != null)
{
if (hitInfo.collider.CompareTag("Enemy"))
{
DestroyProjectile();
hitInfo.collider.GetComponent<Enemy>().TakeDamage(ShootScript.damagePerShot);
}
}
}
the only place your intantiate something in your givin script is in the Destroyed method, and even there it is //commented.
Feel free to delete this question
I'm trying to make enemies follow my player when the player enters the radius area of an enemy, but make the enemy stop following when my bullet hits object or enters radiusArea.
See my gif for more detail:
Gif
script:
using UnityEngine;
using System.Collections;
public class FlyEnemyMove : MonoBehaviour
{
public float moveSpeed;
public float playerRange;
public LayerMask playerLayer;
public bool playerInRange;
PlayerController thePlayer;
// Use this for initialization
void Start()
{
thePlayer = FindObjectOfType<PlayerController>();
}
// Update is called once per frame
void Update()
{
flip();
playerInRange = Physics2D.OverlapCircle(transform.position, playerRange, playerLayer);
if (playerInRange)
{
transform.position = Vector3.MoveTowards(transform.position, thePlayer.transform.position, moveSpeed * Time.deltaTime);
//Debug.Log(transform.position.y);
}
//Debug.Log(playerInRange);
}
void OnDrawGizmosSelected()
{
Gizmos.DrawWireSphere(transform.position, playerRange);
}
void flip()
{
if (thePlayer.transform.position.x < transform.position.x)
{
transform.localScale = new Vector3(0.2377247f, 0.2377247f, 0.2377247f);
}
else
{
transform.localScale = new Vector3(-0.2377247f, 0.2377247f, 0.2377247f);
}
}
}
I hope someone can help me :(
Physics2D.OverlapCircle detects only the collider with the lowest z value (if multiple are in range). So you either need to change the z values so the player has the lowest or you need to work with Physics2D.OverlapCircleAll and check the list to find the player. Or you could change your layers so only the player itself is on that specific layer you feed into the overlap test.
http://answers.unity3d.com/questions/212189/camera-shake.html
I've followed the question's answer above to try and get a camera shake working for my first person camera. But I've tried to modify it so that the camera shakes from an invisible collision box.
So far my camera shake script looks like this;
public bool Shaking;
private float ShakeDecay;
private float ShakeIntensity;
private Vector3 OriginalPos;
private Quaternion OriginalRot;
void Start()
{
Shaking = false;
}
void OnTriggerEnter(Collider collision)
{
if(collision.gameObject.name == "ShakeTrigger")
{
DoShake();
Debug.Log("The camera trigger has hit");
}
}
void Update ()
{
if(ShakeIntensity > 0)
{
transform.position = OriginalPos + Random.insideUnitSphere * ShakeIntensity;
transform.rotation = new Quaternion(OriginalRot.x + Random.Range(-ShakeIntensity, ShakeIntensity)*.2f,
OriginalRot.y + Random.Range(-ShakeIntensity, ShakeIntensity)*.2f,
OriginalRot.z + Random.Range(-ShakeIntensity, ShakeIntensity)*.2f,
OriginalRot.w + Random.Range(-ShakeIntensity, ShakeIntensity)*.2f);
ShakeIntensity -= ShakeDecay;
}
else if (Shaking)
{
Shaking = false;
}
}
void OnGUI() {
if (GUI.Button(new Rect(10, 200, 50, 30), "Shake"))
DoShake();
//Debug.Log("Shake");
}
public void DoShake()
{
OriginalPos = transform.position;
OriginalRot = transform.rotation;
ShakeIntensity = 0.3f;
ShakeDecay = 0.02f;
Shaking = true;
}
I know the code works 100% via the gui button. This script is attached to the camera on the first person controller. An invisible collision box with the tag ShakeTrigger is in the game. However, the debug log doesn't get called at all and I'm unsure why.
If anyone needs any more information just let me know.
Thanks in advance :)
If the script is attached to your camera, then OnTriggerEnter is looking at the camera for a trigger call, not the collision box.
One thing you could do is stick the OnTriggerEnter into a new script and put that inside the collision box. Then have that do a SendMessage along these lines:
GameObject.Find("Camera").SendMessage("DoShake");
EDIT: To answer Jerdak's questions.
The code bellow would be within the TriggerBox:
void Start()
{
...
}
void OnTriggerEnter(Collider collision)
{
if(collision.gameObject.name == "ShakeTrigger")
{
GameObject.Find("Camera").SendMessage("DoShake");
Debug.Log("The camera trigger has hit");
}
}...
and this would be within the Camera:
void Start()
{
...
}
public void DoShake()
{
OriginalPos = transform.position;
OriginalRot = transform.rotation;
ShakeIntensity = 0.3f;
ShakeDecay = 0.02f;
Shaking = true;
}...
This way, triggerbox is responsible for detecting triggers and only ever sends a message to the camera when right kind of object goes through it. The camera is then responsible for doing the shaking.
To shake your camera on the collision or Trigger you need to first Make function of Your Shake that you can also call from other scripts
Something like
public class ShakeCamera : MonoBehavior
{
public bool canShake;
private void Update()
{
if(canShake)
DoShake()
}
public void DoShake()
{
// Shake Logic
}
public void StartShake()
{
canShake = true;
}
public void StopShake()
{
canShake = false;
}
}
And from your other script whenever you trigger the target object you can call it like this
public class TriggerScript: MonoBehavior
{
public ShakeCamera shakeCamera;
private void Start()
{
shakeCamera = FindObjectOfType<ShakeCamera>();
}
void OnTriggerEnter(Collider collision)
{
if(collision.gameObject.tag == "targetTag")// Change Tag accroding to your requirement
{
cameraShake.StartShake();
}
}
void OnTriggerExit(Collider collision)
{
if(collision.gameObject.tag == "targetTag")// Change Tag accroding to your requirement
{
cameraShake.StopShake();
}
}
}
I am attaching one reference video for you, May be it would help you in better camera shake. Hope it was helpful.
You can refer to this video I made https://youtu.be/9X_JXexwfR4
If you have set up rigidbody then change the interpolate from none to interpolate.