Hi developers.
I have a few problem with Server and Client
Players are digging terrain
Firts,[ClientRpc] is working.
Image
if I didn’t use [Command],Client is digging but not showing on server,Thats ok.
But if I use [Command],Client is digging and showing on server but client not see himself hole.
Image
And so strange,example,client digging 2 meters but showing 1 meter on server.
And of course not sees client from client.
I Confused
Code Here
using UnityEngine;
using UnityEngine.Networking;
using UnityEngine.UI;
public class Kazma :NetworkBehaviour
{
public ParticleSystem partikul;
public bool MouseActive = false;
public Terrain myTerrain;
public int SmoothArea;
private int xResolution;
private int zResolution;
public float[,] heights;
private float[,] heightMapBackup;
protected const float DEPTH_METER_CONVERT=0.05f;
protected const float TEXTURE_SIZE_MULTIPLIER = 1.25f;
public int DeformationTextureNum = 1;
protected int alphaMapWidth;
protected int alphaMapHeight;
protected int numOfAlphaLayers;
private float[, ,] alphaMapBackup;
public Transform camTransform;
public float range;
float hitWaitTime;
bool startTime;
void Start()
{
Cursor.visible = false;
xResolution = myTerrain.terrainData.heightmapWidth;
zResolution = myTerrain.terrainData.heightmapHeight;
alphaMapWidth = myTerrain.terrainData.alphamapWidth;
alphaMapHeight = myTerrain.terrainData.alphamapHeight;
numOfAlphaLayers = myTerrain.terrainData.alphamapLayers;
if (Debug.isDebugBuild)
{
heights = myTerrain.terrainData.GetHeights (0, 0, xResolution, zResolution);
heightMapBackup = myTerrain.terrainData.GetHeights(0, 0, xResolution, zResolution);
alphaMapBackup = myTerrain.terrainData.GetAlphamaps(0, 0, alphaMapWidth, alphaMapHeight);
}
}
void Update()
{
if (MouseActive == true)
{
if (Input.GetMouseButtonDown (0))
{
startTime = true;
}
if (startTime == true)
{
DigWaitTimer ();
}
}
}
void DigWaitTimer()
{
hitWaitTime += Time.deltaTime;
if (hitWaitTime > 1)
{
hitWaitTime = 0;
Dig ();
startTime = false;
}
}
public void Dig()
{
if (!isServer)
{
RaycastHit hit;
Ray ray = Camera.main.ScreenPointToRay (Input.mousePosition);
if (Physics.Raycast (ray, out hit, range))
{
partikul.Emit (3);
// area middle point x and z, area width, area height, smoothing distance, area height adjust
CmdraiselowerTerrainArea (hit.point, 2, 2, SmoothArea, -0.0005f);
// area middle point x and z, area size, texture ID from terrain textures
CmdTextureDeformation (hit.point, 2, DeformationTextureNum);
}
}
if (isServer)
{
RaycastHit hit;
Ray ray = Camera.main.ScreenPointToRay (Input.mousePosition);
if (Physics.Raycast (ray, out hit, range))
{
partikul.Emit (3);
// area middle point x and z, area width, area height, smoothing distance, area height adjust
RpcraiselowerTerrainArea (hit.point, 2, 2, SmoothArea, -0.0005f);
// area middle point x and z, area size, texture ID from terrain textures
RpcTextureDeformation (hit.point, 2, DeformationTextureNum);
}
}
}
[Command]
public void CmdraiselowerTerrainArea(Vector3 point, int lenx, int lenz, int smooth,float incdec)
{
int areax;
int areaz;
smooth += 1;
float smoothing;
int terX =(int)((point.x / myTerrain.terrainData.size.x) * xResolution);
int terZ =(int)((point.z / myTerrain.terrainData.size.z) * zResolution);
lenx += smooth;
lenz += smooth;
terX -= (lenx / 2);
terZ -= (lenz / 2);
if (terX < 0) terX = 0;
if (terX > xResolution) terX = xResolution;
if (terZ < 0) terZ = 0;
if (terZ > zResolution) terZ = zResolution;
float[,] heights = myTerrain.terrainData.GetHeights(terX, terZ, lenx, lenz);
float y = heights[lenx/2,lenz/2];
y += incdec;
for (smoothing=1; smoothing < smooth+1; smoothing++)
{
float multiplier = smoothing / smooth;
for (areax = (int)(smoothing/2); areax < lenx-(smoothing/2); areax++)
{
for (areaz = (int)(smoothing/2); areaz < lenz-(smoothing/2); areaz++)
{
if ((areax > -1) && (areaz > -1) && (areax < xResolution) && (areaz < zResolution))
{
heights [areax, areaz] = Mathf.Clamp((float)y*multiplier,0,1);
}
}
}
}
myTerrain.terrainData.SetHeights (terX, terZ, heights);
}
[Command]
public void CmdTextureDeformation(Vector3 pos, float craterSizeInMeters,int textureIDnum)
{
Vector3 alphaMapTerrainPos = GetRelativeTerrainPositionFromPos(pos, myTerrain, alphaMapWidth, alphaMapHeight);
int alphaMapCraterWidth = (int)(craterSizeInMeters * (alphaMapWidth / myTerrain.terrainData.size.x));
int alphaMapCraterLength = (int)(craterSizeInMeters * (alphaMapHeight / myTerrain.terrainData.size.z));
int alphaMapStartPosX = (int)(alphaMapTerrainPos.x - (alphaMapCraterWidth / 2));
int alphaMapStartPosZ = (int)(alphaMapTerrainPos.z - (alphaMapCraterLength/2));
float[, ,] alphas = myTerrain.terrainData.GetAlphamaps(alphaMapStartPosX, alphaMapStartPosZ, alphaMapCraterWidth, alphaMapCraterLength);
float circlePosX;
float circlePosY;
float distanceFromCenter;
for (int i = 0; i < alphaMapCraterLength; i++) //width
{
for (int j = 0; j < alphaMapCraterWidth; j++) //height
{
circlePosX = (j - (alphaMapCraterWidth / 2)) / (alphaMapWidth / myTerrain.terrainData.size.x);
circlePosY = (i - (alphaMapCraterLength / 2)) / (alphaMapHeight / myTerrain.terrainData.size.z);
distanceFromCenter = Mathf.Abs(Mathf.Sqrt(circlePosX * circlePosX + circlePosY * circlePosY));
if (distanceFromCenter < (craterSizeInMeters / 2.0f))
{
for (int layerCount = 0; layerCount < numOfAlphaLayers; layerCount++)
{
//could add blending here in the future
if (layerCount == textureIDnum)
{
alphas[i, j, layerCount] = 1;
}
else
{
alphas[i, j, layerCount] = 0;
}
}
}
}
}
myTerrain.terrainData.SetAlphamaps(alphaMapStartPosX, alphaMapStartPosZ, alphas);
}
[ClientRpc]
public void RpcraiselowerTerrainArea(Vector3 point, int lenx, int lenz, int smooth,float incdec)
{
int areax;
int areaz;
smooth += 1;
float smoothing;
int terX =(int)((point.x / myTerrain.terrainData.size.x) * xResolution);
int terZ =(int)((point.z / myTerrain.terrainData.size.z) * zResolution);
lenx += smooth;
lenz += smooth;
terX -= (lenx / 2);
terZ -= (lenz / 2);
if (terX < 0) terX = 0;
if (terX > xResolution) terX = xResolution;
if (terZ < 0) terZ = 0;
if (terZ > zResolution) terZ = zResolution;
float[,] heights = myTerrain.terrainData.GetHeights(terX, terZ, lenx, lenz);
float y = heights[lenx/2,lenz/2];
y += incdec;
for (smoothing=1; smoothing < smooth+1; smoothing++)
{
float multiplier = smoothing / smooth;
for (areax = (int)(smoothing/2); areax < lenx-(smoothing/2); areax++)
{
for (areaz = (int)(smoothing/2); areaz < lenz-(smoothing/2); areaz++)
{
if ((areax > -1) && (areaz > -1) && (areax < xResolution) && (areaz < zResolution))
{
heights [areax, areaz] = Mathf.Clamp((float)y*multiplier,0,1);
}
}
}
}
myTerrain.terrainData.SetHeights (terX, terZ, heights);
}
[ClientRpc]
public void RpcTextureDeformation(Vector3 pos, float craterSizeInMeters,int textureIDnum)
{
Vector3 alphaMapTerrainPos = GetRelativeTerrainPositionFromPos(pos, myTerrain, alphaMapWidth, alphaMapHeight);
int alphaMapCraterWidth = (int)(craterSizeInMeters * (alphaMapWidth / myTerrain.terrainData.size.x));
int alphaMapCraterLength = (int)(craterSizeInMeters * (alphaMapHeight / myTerrain.terrainData.size.z));
int alphaMapStartPosX = (int)(alphaMapTerrainPos.x - (alphaMapCraterWidth / 2));
int alphaMapStartPosZ = (int)(alphaMapTerrainPos.z - (alphaMapCraterLength/2));
float[, ,] alphas = myTerrain.terrainData.GetAlphamaps(alphaMapStartPosX, alphaMapStartPosZ, alphaMapCraterWidth, alphaMapCraterLength);
float circlePosX;
float circlePosY;
float distanceFromCenter;
for (int i = 0; i < alphaMapCraterLength; i++) //width
{
for (int j = 0; j < alphaMapCraterWidth; j++) //height
{
circlePosX = (j - (alphaMapCraterWidth / 2)) / (alphaMapWidth / myTerrain.terrainData.size.x);
circlePosY = (i - (alphaMapCraterLength / 2)) / (alphaMapHeight / myTerrain.terrainData.size.z);
distanceFromCenter = Mathf.Abs(Mathf.Sqrt(circlePosX * circlePosX + circlePosY * circlePosY));
if (distanceFromCenter < (craterSizeInMeters / 2.0f))
{
for (int layerCount = 0; layerCount < numOfAlphaLayers; layerCount++)
{
//could add blending here in the future
if (layerCount == textureIDnum)
{
alphas[i, j, layerCount] = 1;
}
else
{
alphas[i, j, layerCount] = 0;
}
}
}
}
}
myTerrain.terrainData.SetAlphamaps(alphaMapStartPosX, alphaMapStartPosZ, alphas);
}
protected Vector3 GetNormalizedPositionRelativeToTerrain(Vector3 pos, Terrain terrain)
{
Vector3 tempCoord = (pos - terrain.gameObject.transform.position);
Vector3 coord;
coord.x = tempCoord.x / myTerrain.terrainData.size.x;
coord.y = tempCoord.y / myTerrain.terrainData.size.y;
coord.z = tempCoord.z / myTerrain.terrainData.size.z;
return coord;
}
protected Vector3 GetRelativeTerrainPositionFromPos(Vector3 pos,Terrain terrain, int mapWidth, int mapHeight)
{
Vector3 coord = GetNormalizedPositionRelativeToTerrain(pos, terrain);
return new Vector3((coord.x * mapWidth), 0, (coord.z * mapHeight));
}
}

