XRoom_Unity/Assets/networkMarker.cs
2025-05-31 10:20:20 +03:30

266 lines
10 KiB
C#

using Fusion;
using UnityEngine;
using System.Collections;
using UnityEngine;
using UnityEngine.InputSystem;
using UnityEngine.UI;
using UnityEngine.XR;
using BNG;
public class MarkerNetwork : NetworkBehaviour
{
public NetworkObject box;
private Color GetJoystickColor(float x, float y)
{
// ترکیب رنگ‌ها بر اساس حرکت جوی‌استیک
float red = Mathf.Abs(y); // جهت بالا و پایین باعث تغییر رنگ قرمز
float blue = Mathf.Abs(x); // جهت چپ و راست باعث تغییر رنگ آبی
float green = Mathf.Abs(x * y); // جهت مورب (چپ و بالا / راست و پایین) باعث تغییر رنگ سبز
// به‌روزرسانی رنگ بر اساس مقادیر ورودی
return new Color(red, green, blue); // استفاده از مقادیر قرمز، سبز و آبی برای ساخت رنگ
}
[Range(-1f, 1f)] // محدود کردن مقدار بین -1 تا 1
public float joystickX = 0f;
[Range(-1f, 1f)]
public float joystickY = 0f;
private Vector2 lastValidJoystickInput = Vector2.zero;
Vector2 joystickInputValue;
bool isTouching = false;
private void Update()
{
Vector2 joystickInputValue = Vector2.zero;
// particle.SetActive((Physics.Raycast(RaycastStart.position, RaycastStart.up, out RaycastHit hit, RaycastLength, DrawingLayers) || (rightController.TryGetFeatureValue(UnityEngine.XR.CommonUsages.trigger, out float isPressed) && isPressed > 0.5f) || Input.GetKey(KeyCode.Z)) && HasStateAuthority);
bool isActive = ( Physics.Raycast(RaycastStart.position, RaycastStart.up, out RaycastHit hit, RaycastLength, DrawingLayers)
|| (rightController.TryGetFeatureValue(UnityEngine.XR.CommonUsages.trigger, out float isPressed) && isPressed > 0.5f)
|| Input.GetKey(KeyCode.Z))
&& GetComponent<Grabbable>().BeingHeld&&HasStateAuthority;
particle.SetActive(isActive);
// اگر فعال شد، ویبره بده
if (isActive)
{
rightController.SendHapticImpulse(0, 0.1f, 0.1f); // (کانال, شدت, مدت‌زمان)
}
if (rightController.TryGetFeatureValue(UnityEngine.XR.CommonUsages.primary2DAxisTouch, out isTouching))
{
if (isTouching && rightController.TryGetFeatureValue(UnityEngine.XR.CommonUsages.primary2DAxis, out joystickInputValue))
{
joystickX = joystickInputValue.x;
joystickY = joystickInputValue.y;
if (Mathf.Abs(joystickX) > 0.05f || Mathf.Abs(joystickY) > 0.05f) // یه آستانه بذار که نویز صفرهای ریز رد شه
{
DrawColor = GetJoystickColor(joystickX, joystickY);
lastValidJoystickInput = joystickInputValue;
}
}
else
{
// درحال لمس هست ولی مقدار معنادار نیست یا مرکزیه
// کاری نکن
}
}
else
{
// لمس نکرده، پس مقدار قبلی رو نگه دار
joystickInputValue = lastValidJoystickInput;
}
// if (rightController.TryGetFeatureValue(UnityEngine.XR.CommonUsages.primary2DAxis, out joystickInputValue))
//{
// joystickX = joystickInputValue.x; // محور x (چپ و راست)
// joystickY = joystickInputValue.y; // محور y (بالا و پایین)
// if(Mathf.Abs(joystickX) ==1&& Mathf.Abs(joystickY) == 1)
// DrawColor = GetJoystickColor(joystickX, joystickY);
// }
// else{
// // joystickX+=Input.GetKey(KeyCode.K)?.1f:-.1f;
//}
if (rightController.TryGetFeatureValue(UnityEngine.XR.CommonUsages.trigger, out float triggerValue))
{
if (previousTriggerValue > 0.5f && triggerValue <= 0.5f) // اگر تریگر از فشرده بودن به رها شدن تغییر کرد
{
CreateBoxForLine(); // ایجاد باکس و قرار دادن خط داخل آن
}
previousTriggerValue = triggerValue; // ذخیره مقدار فعلی برای بررسی فریم بعدی
}else if (Input.GetKeyUp(KeyCode.Z))
{
CreateBoxForLine(); // ایجاد باکس و قرار دادن خط داخل آن
}
// تغییر رنگ بر اساس ورودی جوی‌استیک
transform.Find("GFX").GetChild(1).GetComponent<MeshRenderer>().material.color = DrawColor;
transform.Find("GFX").GetChild(3).GetComponent<MeshRenderer>().material.color = DrawColor;
}
private float previousTriggerValue = 0f; // ذخیره مقدار قبلی تریگر
public Vector3[] localOffsets;
private Vector3 GetLineCenterPoint(LineRenderer line)
{
Vector3 sum = Vector3.zero;
int count = line.positionCount;
if (count == 0) return lastDrawPoint;
for (int i = 0; i < count; i++)
{
sum += line.GetPosition(i);
}
return sum / count;
}
private void CreateBoxForLine()
{
if (currentLineRenderer == null || !Object.HasInputAuthority) return; // اطمینان از وجود خط و مجوز کنترل
// ایجاد باکس در آخرین نقطه ترسیم‌شده
// NetworkObject newBox = Runner.Spawn(box, lastDrawPoint, Quaternion.identity, Runner.LocalPlayer);
Vector3 centerPoint = GetLineCenterPoint(currentLineRenderer);
NetworkObject newBox = Runner.Spawn(box, centerPoint, Quaternion.identity, Runner.LocalPlayer);
// تنظیم خط به عنوان زیرمجموعه‌ی باکس
// ارسال درخواست به همه‌ی کلاینت‌ها برای افزودن اسکریپت Draws
RPC_SetLineParent(newBox);
}
// این متد را به عنوان یک RPC تعریف کنید تا در کل شبکه اجرا شود
[Rpc(RpcSources.InputAuthority, RpcTargets.All)]
private void RPC_SetLineParent(NetworkObject newBox)
{
if (currentLineRenderer == null) return;
Draws drawComponent = currentLineRenderer.gameObject.GetComponent<Draws>();
if (drawComponent == null)
{
drawComponent = currentLineRenderer.gameObject.AddComponent<Draws>();
}
drawComponent.parent = newBox.transform;
}
public Material DrawMaterial;
public Color DrawColor = Color.red;
public float LineWidth = 0.015f;
public void Start(){
rightController = InputDevices.GetDeviceAtXRNode(XRNode.RightHand );
}
private UnityEngine.XR.InputDevice rightController;
public Transform RaycastStart;
public LayerMask DrawingLayers;
public float RaycastLength = 0.01f;
public float MinDrawDistance = 0.002f;
private Vector3 lastDrawPoint;
private LineRenderer currentLineRenderer;
private bool isDrawing = false;
private bool wasDrawingLastFrame = false; // برای تشخیص قطع و وصل اتصال
public void StartDrawing()
{
isDrawing = true;
StartCoroutine(DrawRoutine());
}
public void StopDrawing()
{
isDrawing = false;
}
public Transform tip;
public GameObject particle;
IEnumerator DrawRoutine()
{
while (isDrawing)
{
bool isCurrentlyDrawing = false;
if (Physics.Raycast(RaycastStart.position, RaycastStart.up, out RaycastHit hit, RaycastLength, DrawingLayers)|| ( rightController.TryGetFeatureValue(UnityEngine.XR.CommonUsages.trigger, out float isPressed) && isPressed>0.5f)||Input.GetKey(KeyCode.Z))
// if ( ( rightController.TryGetFeatureValue(UnityEngine.XR.CommonUsages.trigger, out float isPressed) && isPressed>0.5f)||Input.GetKey(KeyCode.Z))
{
isCurrentlyDrawing = true;
Vector3 drawPosition =tip.position;
Quaternion drawRotation =tip.rotation;
if(!hit.transform){
}else{
drawPosition = hit.point + (-RaycastStart.up * 0.0005f);
drawRotation = Quaternion.FromToRotation(Vector3.back, hit.normal);
}
float lineWidth = LineWidth;
// اگر قبلاً رسم نمی‌کردیم اما الان اتصال برقرار شده، خط جدید ایجاد کن و برای همه بفرست
if (!wasDrawingLastFrame)
{
RPC_CreateNewLineRenderer(DrawColor);
}
if (Vector3.Distance(lastDrawPoint, drawPosition) > MinDrawDistance)
{
lastDrawPoint = drawPosition;
RPC_DrawPoint(drawPosition, DrawColor);
}
}
// به‌روزرسانی وضعیت اتصال برای فریم بعدی
wasDrawingLastFrame = isCurrentlyDrawing;
yield return null;
}
}
[Rpc(RpcSources.All, RpcTargets.All)]
private void RPC_DrawPoint(Vector3 position, Color lineColor)
{
if (currentLineRenderer == null)
{
CreateNewLineRenderer(lineColor);
}
DrawColor = lineColor;
currentLineRenderer.positionCount += 1;
currentLineRenderer.SetPosition(currentLineRenderer.positionCount - 1, position);
}
[Rpc(RpcSources.StateAuthority, RpcTargets.All)]
private void RPC_CreateNewLineRenderer(Color draw)
{
DrawColor = draw;
CreateNewLineRenderer(DrawColor);
}
private void CreateNewLineRenderer(Color drawColor)
{
GameObject drawObj = new GameObject("DrawLine");
currentLineRenderer = drawObj.AddComponent<LineRenderer>();
currentLineRenderer.tag = "draw";
currentLineRenderer.material = DrawMaterial;
currentLineRenderer.startColor = drawColor;
currentLineRenderer.endColor = drawColor;
currentLineRenderer.startWidth = LineWidth;
currentLineRenderer.endWidth = LineWidth;
currentLineRenderer.useWorldSpace = true;
currentLineRenderer.positionCount = 0;
// drawObj.gameObject.layer = LayerMask.NameToLayer("draw");
// MarkerEraser.instance.allLines.Add(currentLineRenderer);
// NetworkMarkerEraser.instance.allLines.Add(currentLineRenderer);
}
}