No Unity, preciso mover um CharacterController de v2 para v3. Tenho as seguintes informações: o ponto central do círculo (v1); a posição atual do personagem na parte externa do círculo (v2); o ângulo (a). Como calculo o vetor de movimento para o CharacterController para que ele se mova de v2 para v3?
Criei um prefab simples chamado ScorePopup. Ele tem um TextMeshPro
componente. Ele também tem um Animator
que move o texto para cima em 2 unidades do mundo e desbota a cor em 1 segundo. Então, no animador, ele tem
ScorePopup: Text Mesh Pro.Font Color - goes from 1 to 0 over 1 second.
ScorePopup: Anchored Position
Anchored Position.x (stays at 0)
Anchored Position.y - goes from 0 to 2 over 1 second.
Agora, imagine um jogo em que um inimigo está se movendo da direita para a esquerda. Ele é atingido por uma bala. Quero instanciar este ScorePopup na posição em que o inimigo foi atingido.
Tentei instanciá-lo no meu script de jogo:
GameObject go = Instantiate(scorePopupPrefab, enemy.transform.position, Quaternion.identity);
go.GetComponent<TMP_Text>().text = score.ToString();
O problema é que o ScorePopup não aparece na posição do inimigo - ele aparece em 0,0 na minha cena, provavelmente por causa dos Anchored Position
valores na animação.
Então tentei instanciar o ScorePopup no meu script inimigo:
GameObject go = Instantiate(scorePopupPrefab, transform.position, Quaternion.identity, transform);
Isso coloca corretamente o scorePopup onde o inimigo está. No entanto, o scorePopup se move para a esquerda com o inimigo. Quero que o score popup apareça na posição de ataque no espaço de cena/mundo e faça sua animação lá. Ele não deve se mover com o inimigo.
Qual é a solução aqui? Como posso instanciar um prefab na minha cena em uma posição designada se o prefab tem uma animação de posição interna? Isso é para o cenário muito comum em que você vê uma pontuação flutuar para cima quando um jogador ganha pontos ao atacar ou obter um objeto.
Editar: O prefab de texto não tem uma tela. Ele foi criado como um objeto vazio e tem um TMPRo - Text
componente (e um Animator) adicionado a ele para exibir o texto.
Eu também tentei isso:
public class ScorePopup : MonoBehaviour
{
private Animator animator;
void Awake()
{
animator = GetComponent<Animator>();
if (animator != null)
{
animator.enabled = false;
StartCoroutine(EnableAnimatorAfterDelay(0.1f));
}
}
IEnumerator EnableAnimatorAfterDelay(float delay)
{
yield return new WaitForSeconds(delay);
animator.enabled = true;
}
}
Ele aparece brevemente na posição correta, mas depois muda para 0,0 quando a animação é ativada :(
Eu tenho este pedaço de código:
foreach (DynamicBuffer<Items> items in SystemAPI.Query<DynamicBuffer<Items>>())
{
...
}
Estou tentando modificar um elemento específico de items
. É assim que estou tentando fazer isso:
items[3] = modifiedItem;
Mas eu recebo o erro
Não é possível modificar membros de 'itens' porque é uma 'variável de iteração foreach'.
Como posso modificar os elementos de items
?
Fiz alguns clipes de animação extras e a mera existência deles faz com que o player não consiga se mover. Não sei por que, quando excluo os novos clipes de animação, consigo mover o player novamente. Tentei desfazer o código para ver se era o código, mas não era.
Estou tentando mover suavemente um objeto do ponto a para o ponto b:
Instantiate(cat, OffScreenLeft(), Quaternion.identity);
Debug.Log("start position: " + OffScreenLeft());
Debug.Log("end position: " + InPosition());
StartCoroutine(MoveFromTo(cat.transform, OffScreenLeft(), InPosition(), 3f));
IEnumerator MoveFromTo(Transform objectToMove, Vector3 a, Vector3 b, float speed) {
float step = (speed / (a - b).magnitude) * Time.fixedDeltaTime;
float t = 0;
while (t <= 1.0f) {
t += step; // Goes from 0 to 1, incrementing by step each time
objectToMove.position = Vector3.Lerp(a, b, t); // Move objectToMove closer to b
yield return new WaitForFixedUpdate();
}
objectToMove.position = b;
Debug.Log("move complete cat: " + cat.transform.position);
}
Aqui está a saída de depuração:
start position: (-20.34, 4.33)
end position: (-8.67, 4.33)
move complete cat: (-8.67, 4.33, 0.00)
A saída de depuração mostra que o gato deveria ter se movido. Mas ele ainda aparece fora da tela, deixado em sua posição original. O que estou esquecendo?
Eu tenho um objeto Meteor e um Player. Ambos com RigidBody2d e Colliders2d. O colisor de meteoros tem "Is Trigger" marcado e tem um script com OnCollisionEnter2D() implementado, mas a colisão não está funcionando quando o meteoro atinge o player:
private void OnCollisionEnter2D(Collision2D other) {
Debug.Log(other.gameObject.tag);
Destroy(other.gameObject);
}
}
-Meteoro-
-Jogador-
Visualizar
Em uma corrotina, estou definindo a velocidade de um corpo rígido para seguir a localização da tela de toque:
rb.velocity = direction * touchDragPhysicsSpeed;
Mas eu também quero que sua rotação tenda de volta para zero graus. Como posso fazer isso?
A IA continua me dizendo para fazer algo assim:
Quaternion targetRotation = Quaternion.Euler(Vector3.zero);
rb.MoveRotation(Quaternion.Slerp(rb.rotation, targetRotation, rotationCorrectionSpeed));
Mas essa linha MoveRotation dá o erro:
Argumento 1: não é possível converter de 'float' para 'UnityEngine.Quaternion'
Essa é a abordagem correta? Se sim, como posso corrigir o erro? Ou há uma maneira melhor?
O código a seguir funciona para clicar e arrastar um objeto:
private void MousePressed(InputAction.CallbackContext context)
{
Vector2 mousePosition = Input.mousePosition;
Vector3 worldPosition = mainCamera.ScreenToWorldPoint(new Vector3(mousePosition.x, mousePosition.y, -mainCamera.transform.position.z));
worldPosition.z = 0;
Collider2D hitCollider = Physics2D.OverlapPoint(worldPosition);
if (hitCollider != null)
{
StartCoroutine(DragUpdate(hitCollider.gameObject));
}
}
private IEnumerator DragUpdate(GameObject clickedObject)
{
float initialDistance = Vector3.Distance(clickedObject.transform.position, mainCamera.transform.position);
clickedObject.TryGetComponent<Rigidbody2D>(out var rb);
while (mouseClick.ReadValue<float>() != 0) {
Ray ray = mainCamera.ScreenPointToRay(Mouse.current.position.ReadValue());
if (rb != null) {
Vector3 direction = ray.GetPoint(initialDistance) - clickedObject.transform.position;
rb.velocity = direction * mouseDragPhysicsSpeed;
yield return waitForFixedUpdate;
} else {
clickedObject.transform.position = Vector2.SmoothDamp(clickedObject.transform.position, ray.GetPoint(initialDistance), ref velocity, mouseDragSpeed);
yield return null;
}
}
}
O problema é que o objeto primeiro se move de modo que seu centro fique no cursor. Como posso manter o deslocamento inicial para que o cursor permaneça no mesmo local relativo ao objeto como quando ele começou a arrastar?
Estou aberto a quaisquer outras sugestões para melhorar este código - sou novo em Unity/C#. Obrigado!
Estou fazendo um jogo multijogador e no código onde estou fazendo itens de pegar e largar. Estou tendo um erro que player.transform.childCount está retornando 3 logo depois que adiciono filhos e outros filhos abaixo do jogador.
Eu tento adicionar algum debug.log e a saída está no lado do cliente "3: 1" e "3" e no lado do host está a saída "4: 0", então no lado do host está tudo bem, mas no lado do cliente está retornando o valor errado
Obrigado por qualquer resposta
public void AddItem(ItemData itemData)
{
if(itemData == null)
return;
this.itemData = itemData;
icon.sprite = itemData.icon;
icon.enabled = true;
if (player == null)
player = NetworkManager.Singleton.SpawnManager.GetLocalPlayerObject().gameObject;
if (player != null)
{
NetworkObject networkObject = player.GetComponent<NetworkObject>();
if (networkObject != null)
{
Debug.Log(player.transform.childCount + ": 1");
AddItemToHandServerRpc(itemData.index, networkObject.NetworkObjectId);
Debug.Log(player.transform.childCount);
if (player.transform.childCount == 4)
{
GameObject item = player.transform.GetChild(player.transform.childCount - 1).gameObject;
item.GetComponent<SetPossionToHand>().enabled = true;
item.transform.localScale = new Vector3(.01f, .01f, .01f);
}
else
{
Debug.Log("fsjfhshuyferh");
}
}
else
Debug.Log("none");
}
else
{
Debug.LogError("Hand object is not properly initialized or is disabled.");
}
}
public void ClearSlot(bool delete)
{
itemData = null;
icon.sprite = null;
icon.enabled = false;
if (player.transform.childCount == 4 && delete)
{
if (player == null)
player = NetworkManager.Singleton.SpawnManager.GetLocalPlayerObject().gameObject;
GameObject item = player.transform.GetChild(player.transform.childCount - 1).gameObject;
DespawnObjectServerRpc(item.GetComponent<NetworkObject>().NetworkObjectId);
}
}
[ServerRpc]
void AddItemToHandServerRpc(int index, ulong handId)
{
GameObject item = list.prefabs[index];
var instance = Instantiate(item);
var instanceNetworkObject = instance.GetComponent<NetworkObject>();
Transform player = NetworkManager.Singleton.SpawnManager.SpawnedObjects[handId].gameObject.transform;
instanceNetworkObject.SpawnWithOwnership(handId);
instanceNetworkObject.TrySetParent(player, false);
Debug.Log(player.transform.childCount + ": 0");
}
lado do cliente:
lado do anfitrião:
Estou tentando ocultar minha interface de usuário no Unity, mas uiObject.SetActive(false);
redefine eventos de clique e cores para todos os objetos naquele gameObject da interface de usuário do Unity.
Depois de desabilitar e habilitar: Como devo ocultar a interface do usuário quando ela não for necessária?
Saúde.