Взаимодействие объектов с помощью прикосновенияC#

Место общения программистов C#
Ответить
Anonymous
 Взаимодействие объектов с помощью прикосновения

Сообщение Anonymous »

Я работаю над проектом, который обнаруживает некоторые изображения. Я сделал довольно простой скрипт, который позволяет мне сканировать 5 изображений, а затем размещать 5 соответствующих 3D-префабов в соответствии с каждым изображением. Также есть текст, который показывает имя отсканированного изображения, если этот процесс прошел успешно, или ограниченное отслеживание, если мы не сканируем соответствующие изображения. В основном скрипт выглядит так:

Код: Выделить всё

using UnityEngine;
using UnityEngine.XR.ARFoundation;
using UnityEngine.XR.ARSubsystems;
using System.Collections.Generic;
using TMPro;

public class MultipleImageTracker : MonoBehaviour
{
[System.Serializable]
public struct TrackableImage
{
public string imageName;
public GameObject prefabToInstantiate;
}

public List trackableImages;
public GameObject statusTextPrefab;
public float statusDisplayTime = 5f;
public Canvas arCanvas;

private ARTrackedImageManager trackedImageManager;
private Dictionary spawnedPrefabs = new Dictionary();
private Dictionary statusTexts = new Dictionary();
private Dictionary lastTrackingStates = new Dictionary();
private GameObject currentActiveStatusText;

private void Awake()
{
trackedImageManager = FindObjectOfType();
if (arCanvas == null)
{
Debug.LogError("AR Canvas is not assigned!");
}
}

private void OnEnable()
{
trackedImageManager.trackedImagesChanged += OnTrackedImagesChanged;
}

private void OnDisable()
{
trackedImageManager.trackedImagesChanged -= OnTrackedImagesChanged;
}

private void OnTrackedImagesChanged(ARTrackedImagesChangedEventArgs eventArgs)
{
foreach (var trackedImage in eventArgs.added)
{
UpdateImage(trackedImage);
}

foreach (var trackedImage in eventArgs.updated)
{
UpdateImage(trackedImage);
}

foreach (var trackedImage in eventArgs.removed)
{
string imageName = trackedImage.referenceImage.name;
if (spawnedPrefabs.ContainsKey(imageName))
{
Destroy(spawnedPrefabs[imageName]);
spawnedPrefabs.Remove(imageName);
}
if (statusTexts.ContainsKey(imageName))
{
Destroy(statusTexts[imageName]);
statusTexts.Remove(imageName);
}
lastTrackingStates.Remove(imageName);
}
}

private void UpdateImage(ARTrackedImage trackedImage)
{
string imageName = trackedImage.referenceImage.name;
Vector3 position = trackedImage.transform.position;
TrackableImage trackableImage = trackableImages.Find(x =>  x.imageName == imageName);
if (trackableImage.prefabToInstantiate != null)
{
UpdateSpawnedPrefab(trackableImage, imageName, position, trackedImage.trackingState);
UpdateStatusText(imageName, trackedImage.trackingState);
}
}

private void UpdateSpawnedPrefab(TrackableImage trackableImage, string imageName, Vector3 position, TrackingState trackingState)
{
if (spawnedPrefabs.ContainsKey(imageName))
{
spawnedPrefabs[imageName].transform.position = position;
spawnedPrefabs[imageName].SetActive(trackingState == TrackingState.Tracking);
}
else
{
GameObject prefabInstance = Instantiate(trackableImage.prefabToInstantiate, position, Quaternion.identity);
prefabInstance.AddComponent();
spawnedPrefabs[imageName] = prefabInstance;
}
}

private void UpdateStatusText(string imageName, TrackingState currentTrackingState)
{
if (!lastTrackingStates.ContainsKey(imageName) || lastTrackingStates[imageName] != currentTrackingState)
{
ShowStatusText(imageName, currentTrackingState);
lastTrackingStates[imageName] = currentTrackingState;
}
}

private void ShowStatusText(string imageName, TrackingState trackingState)
{
if (currentActiveStatusText != null)
{
StopAllCoroutines();
currentActiveStatusText.SetActive(false);
}

GameObject statusTextObject;
if (!statusTexts.ContainsKey(imageName))
{
statusTextObject = Instantiate(statusTextPrefab, arCanvas.transform);
statusTexts[imageName] = statusTextObject;
RectTransform rectTransform = statusTextObject.GetComponent();
rectTransform.anchorMin = new Vector2(1, 1);
rectTransform.anchorMax = new Vector2(1, 1);
rectTransform.anchoredPosition = new Vector2(-200, -200);
rectTransform.sizeDelta = new Vector2(200, 50);
}
else
{
statusTextObject = statusTexts[imageName];
}

TextMeshProUGUI tmp = statusTextObject.GetComponent();
if (tmp != null)
{
switch (trackingState)
{
case TrackingState.Tracking:
tmp.color = Color.green;
tmp.text = $"Recognized: {imageName}";
break;
case TrackingState.Limited:
tmp.color = Color.yellow;
tmp.text = "Tracking limited...";
break;
case TrackingState.None:
tmp.color = Color.red;
tmp.text = "Lost tracking";
break;
}
}

statusTextObject.SetActive(true);
currentActiveStatusText = statusTextObject;
StartCoroutine(HideStatusText(imageName));
}

private System.Collections.IEnumerator HideStatusText(string imageName)
{
yield return new WaitForSeconds(statusDisplayTime);
if (statusTexts.ContainsKey(imageName) && statusTexts[imageName] == currentActiveStatusText)
{
statusTexts[imageName].SetActive(false);
currentActiveStatusText = null;
}
}
}
Теперь я хочу добавить некоторые взаимодействия с моими префабами, которые отображаются в соответствии с изображениями. Если я коснусь префаба, он должен увеличиться в два раза и вернуться к нормальному размеру, как простая анимация. Если я снова коснусь этого префаба, он прекратит анимацию и вернется к исходному масштабу. Я пробовал что-то вроде этого:

Код: Выделить всё

using UnityEngine;

public class TouchInputHandler : MonoBehaviour
{
private bool isScaled = false;

void Update()
{
if (Input.touchCount > 0 && Input.touches[0].phase == TouchPhase.Began)
{
Ray ray = Camera.main.ScreenPointToRay(Input.touches[0].position);
RaycastHit[] hits = Physics.RaycastAll(ray);

Debug.Log("Touch detected");

foreach (RaycastHit hit in hits)
{
Debug.Log($"Raycast hit: {hit.transform.name}");

if (hit.transform == transform)
{
Debug.Log($"Object {hit.transform.name} was touched");

if (!isScaled)
{
StartCoroutine(ScaleObject(transform, 2f, 0.5f));
}
else
{
StartCoroutine(ScaleObject(transform, 1f, 0.5f));
}
isScaled = !isScaled;
}
}
}
}

private System.Collections.IEnumerator ScaleObject(Transform obj, float targetScale, float duration)
{
Vector3 originalScale = obj.localScale;
Vector3 destinationScale = originalScale * targetScale;

float currentTime = 0.0f;

while (currentTime 

Подробнее здесь: [url]https://stackoverflow.com/questions/79084005/object-interaction-with-touch[/url]
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «C#»