[Dicas do Unity] Use três métodos para obter o efeito de zoom da mira

Comparação do efeito final

Insira a descrição da imagem aqui

Prefácio

Em muitos jogos de tiro, o efeito de zoom da mira é uma parte importante para melhorar a precisão do tiro e a experiência do jogo. Como um mecanismo popular de desenvolvimento de jogos, o Unity oferece uma variedade de métodos para obter o efeito de zoom da mira. Este artigo apresentará três métodos de implementação comuns e discutirá suas vantagens e desvantagens, respectivamente.

Primeiro, apresentaremos como obter um efeito de zoom ampliado ajustando o campo de visão da câmera. Em segundo lugar, discutiremos como usar o Shader para obter o efeito de ampliação da visão e como usar o Render Texture para simular o efeito de zoom. Cada método tem seus cenários de aplicação e aplicabilidade exclusivos. Neste artigo, nos aprofundaremos nos cenários específicos de implementação e uso desses três métodos para ajudar os desenvolvedores a escolher o método de implementação apropriado de acordo com suas próprias necessidades.

Quer você seja um desenvolvedor iniciante ou experiente, este artigo fornecerá tutoriais abrangentes e exemplos de código para ajudá-lo a entender e usar melhor o efeito de zoom de ampliação visual no Unity. Vamos começar a explorar essas tecnologias interessantes!

A primeira maneira

Ajustar o valor FOV da câmera

public class RifleScopeZoom : MonoBehaviour
{
    
    
    [SerializeField] private Camera playerCamera;
    [SerializeField] private float zoomSpeed = 10f;
    [SerializeField] private float minFOV = 20f;
    [SerializeField] private float maxFOV = 60f;

    private void Update()
    {
    
    
        // 获取滚轮滑动的值
        float scrollValue = Input.GetAxis("Mouse ScrollWheel");
        
        // 根据滚轮滑动的值调整 FOV
        playerCamera.fieldOfView -= scrollValue * zoomSpeed;
        
        // 限制 FOV 的范围在最小值和最大值之间
        playerCamera.fieldOfView = Mathf.Clamp(playerCamera.fieldOfView, minFOV, maxFOV);
    }
}

Este é o primeiro método de implementação
Insira a descrição da imagem aqui
. Como você pode ver, é muito simples. Tudo o que faz é ajustar os principais parâmetros da câmera. A vantagem deste método é que ele tem um bom desempenho. Você não precisa de nenhum novo Shader ou outra câmera, mas só precisa ajustar o FOV da câmera. , mas a desvantagem é que não parece muito bom. Idealmente, gostaríamos apenas de ampliar o objeto visto pelo osciloscópio, mas agora a imagem inteira é ampliada.

Além disso, se o modelo da sua mira não for oco e transparente, talvez você não consiga usar esse método, como uma mira de rifle de precisão. No meu exemplo abaixo, só posso remover a mira.
Insira a descrição da imagem aqui

Método dois

Para o segundo método, precisaremos usar o Shader para ampliar a imagem atrás de um objeto.

1. Crie um ambiente URP

Se você não entendeu, pode ler meu artigo anterior, que ensina como configurar o ambiente URP: Usando Shader Graph para obter o efeito de dobra mundial de Animal Crossing: Friends

2. Colocação de ativo de pipeline de renderização universal

Como os nós Scene Depth e Scene Color foram usados ​​no experimento para obter as informações do buffer de profundidade e do buffer de cores, é necessário verificar Depth Texture e Opaque Texture no Universal Render Pipeline Asset, como segue.
Insira a descrição da imagem aqui

3. Aqui criamos um novo ShaderGraph fosco

Insira a descrição da imagem aqui

4. Configuração da imagem principal

Como o espelho é transparente, você precisa definir a propriedade Tipo de Superfície como Transparente nas Configurações do Gráfico do gráfico principal.
Insira a descrição da imagem aqui

4. Crie um novo material e monte-o

Para conseguir esse efeito coloquei uma bola no escopo, deixei bem plana, simulei um efeito de espelho e amarrei o material com o ShaderGraph frontal
Insira a descrição da imagem aqui

5. A seguir está o diagrama de conexão do shaderGraph

Insira a descrição da imagem aqui
O nó Scene Color é usado aqui para gerar a cor da cena atrás do objeto e, em seguida, os nós Tilling e offset são usados ​​para modificar o valor Tilling para obter amplificação. Em seguida, as coordenadas da tela do objeto são usadas. Este é o ponto mais complexo ObjectScreenPosition. Este parâmetro precisa ser ajustado de acordo. O osciloscópio se move e é constantemente modificado.

6. Adicionado um novo script para controlar o ObjectScreenPosition a ser modificado continuamente conforme o escopo se move.

Então eu tenho outro script aqui, o RifleScopeShaderScreenPos. Sua função é converter as coordenadas mundiais do objeto para as coordenadas da tela e depois inseri-las no Shader, então esse Shader não vai ampliar todas as telas, ele só vai ampliar as coisas que estão no Shader. escopo.

public class RifleScopeShaderScreenPos : MonoBehaviour
{
    
    
    // Shader 材质
    [SerializeField] private Material material;

    private void Update()
    {
    
    
        // 获取物体在屏幕上的像素坐标
        Vector2 screenPixels = Camera.main.WorldToScreenPoint(transform.position);
        // 将像素坐标转换为 0-1 的范围
        screenPixels = new Vector2(screenPixels.x / Screen.width, screenPixels.y / Screen.height);
        // 将物体的屏幕坐标传递给 Shader
        material.SetVector("_ObjectScreenPosition", screenPixels);
    }
}

6. Adicionado novo script control_ZoomAmount para realizar o efeito de zoom da roda de rolagem

public class RifleScopeZoomMaterial : MonoBehaviour
{
    
    
    [SerializeField] private float zoomSpeed = 10f;
    [SerializeField] private float min  = 0f;
    [SerializeField] private float max = 1f;
    [SerializeField] private Material zoomMaterial;

    private void Update()
    {
    
    
        // 获取滚轮滑动的值
        float scrollValue = Input.GetAxis("Mouse ScrollWheel");
        scrollValue = zoomMaterial.GetFloat("_ZoomAmount") + scrollValue;

        // 限制的范围在最小值和最大值之间
        scrollValue = Mathf.Clamp(scrollValue, min, max);
        
        zoomMaterial.SetFloat("_ZoomAmount", scrollValue);
    }
}

Insira a descrição da imagem aqui
Comparado com o método anterior, a vantagem é que ele apenas amplia o que a visão vê, de modo que as coisas fora da visão não mudam. Outra vantagem é que, comparado ao próximo método, este método não exige muito desempenho. Existe apenas um O sombreador e a câmera são renderizados apenas uma vez. É claro que existem desvantagens. Um possível problema é que, quando você aumenta o zoom, a imagem fica assim.
Insira a descrição da imagem aqui
Quando a ampliação não é muito alta, a imagem fica aceitável, mas quando você aumenta o zoom quanto maior, mais você obterá uma imagem em mosaico, isso está relacionado à resolução da imagem. O Shader simplesmente amplia a imagem sem alterar sua resolução, portanto, quanto maior a imagem, mais óbvio será o mosaico. Se a taxa de ampliação não for Este é um bom método se for muito grande. Ele também tem o mesmo problema de antes, ou seja, se o seu modelo de osciloscópio não for oco e transparente, este método pode não ser adequado.

A terceira maneira

Temos que usar o recurso de renderização de textura, que essencialmente renderiza a imagem da câmera em uma textura.

1. Adicionada nova câmera de renderização

Portanto, precisamos de uma nova câmera e, em seguida, arraste-a para frente, agora você pode arrastá-la na frente do osciloscópio ou diretamente no cano e, em seguida, aumentar o zoom puxando o FOV para baixo
Insira a descrição da imagem aqui

2. Crie uma textura de renderização

Vamos criar outra textura de renderização. Aqui definimos principalmente o tamanho. Isso depende principalmente da resolução do player e do tamanho da visão na tela. Aqui 1024*1024 é quase suficiente.

Insira a descrição da imagem aqui
Desta forma, configuramos e deixamos a câmera enviar a imagem renderizada para esta textura.
Insira a descrição da imagem aqui
Desta forma, podemos ver que a imagem da câmera foi renderizada nesta textura.
Insira a descrição da imagem aqui

3. Vincular textura de renderização

Em seguida, para exibir a imagem no osciloscópio, colocamos um Quad diretamente dentro do osciloscópio. Só precisamos arrastar a textura de renderização para obter a imagem do osciloscópio.
Insira a descrição da imagem aqui
Isso tem o efeito. Aqui está a imagem ampliada da câmera.
Insira a descrição da imagem aqui

4. Resolva o problema do molde de uso de lentes

Ainda há um pequeno problema, que é que o quadrante da minha porta é quadrado e o escopo é redondo, então você verá que está um pouco através do molde.
Insira a descrição da imagem aqui
Uma solução muito simples é apenas fazer um corte de transparência
Insira a descrição da imagem aqui
aqui. também um pré-fabricado de corte de transparência, apenas certifique-se de ir ao painel de configurações e ativar o clipe Alpha.
Insira a descrição da imagem aqui
Depois de terminar, clique no AlphaClipMask aqui e selecione uma textura circular com um fundo transparente.
Insira a descrição da imagem aqui
Quando terminar, você verá que o a textura fora da máscara foi cortada. Ela mantém apenas a moldura intermediária
Insira a descrição da imagem aqui

5. Controle de script para obter efeito de zoom

A última etapa é processar o script. Tudo o que precisamos fazer é ajustar o FOV da câmera de textura de renderização. Podemos reutilizar o código anterior. Lembre-se de mudar a câmera para nossa câmera de renderização em vez da câmera principal.

public class RifleScopeZoom : MonoBehaviour
{
    
    
    [SerializeField] private Camera playerCamera;
    [SerializeField] private float zoomSpeed = 10f;
    [SerializeField] private float minFOV = 20f;
    [SerializeField] private float maxFOV = 60f;

    private void Update()
    {
    
    
        // 获取滚轮滑动的值
        float scrollValue = Input.GetAxis("Mouse ScrollWheel");
        
        // 根据滚轮滑动的值调整 FOV
        playerCamera.fieldOfView -= scrollValue * zoomSpeed;
        
        // 限制 FOV 的范围在最小值和最大值之间
        playerCamera.fieldOfView = Mathf.Clamp(playerCamera.fieldOfView, minFOV, maxFOV);
    }
}

Efeito
Insira a descrição da imagem aqui
Posso ampliar onde eu quiser, como vocês podem ver não há problema de mosaico comparado ao método anterior, e esse método tem uma característica interessante, ou seja, a imagem na mira muda mesmo quando minha arma não está levantada
Insira a descrição da imagem aqui
. A vantagem é que, como estou usando outra câmera, posso fazer algumas coisas interessantes, como usar 后处理efeitos diferentes, adicionar um efeito de profundidade de campo na câmera principal e, como a textura de renderização está tão próxima da câmera, não fica desfocado e tudo lá fora fica desfocado
Insira a descrição da imagem aqui

Insira a descrição da imagem aqui
Pessoalmente falando, isso parece melhor. A imagem fora do escopo está desfocada, mas a imagem interna ainda está nítida. Se desejar, você pode mover o espelho para frente para usar outros efeitos de pós-processamento. Você pode realizar 镜内热成像ou 夜视效果a imagem fora do espelho permanece normal.

Claro, este método também tem um grande problema, 缺点ou seja 性能问题, este método usa uma textura de renderização para exibir a imagem da segunda câmera. Em essência, a imagem é renderizada duas vezes. Se o jogo que você está fazendo estiver no PC, isso pode não ser um grande problema. Se for um jogo para celular, pode ser um grande problema. Se você puder arcar com o custo de desempenho, este método é o melhor.

Resumir

Ok, você aprendeu esses três métodos de ampliação do osciloscópio. O primeiro método é adequado para quem tem 性能优先necessidades ou deseja encontrar uma maneira de alcançá-lo. O segundo método e o último lhe darão resultados. Escolha um método adequado para usar na sua aplicação, no projeto!最简单稍优于第一
最好的瞄具
Insira a descrição da imagem aqui

referência

【Vídeo】https://www.youtube.com/watch?v=9g2VqJvWnQI

fim

Presentes de rosas, entregue uma fragrância! Se o conteúdo do artigo for útil para você, não seja mesquinho com seus 点赞评论和关注comentários para que eu possa receber feedback o mais rápido possível. Cada feedback seu 支持é a maior motivação para continuar criando. Claro, se você encontrar 存在错误algo no artigo 更好的解决方法, fique à vontade para comentar e me enviar uma mensagem privada!

Ok, estou 向宇, https://xiangyu.blog.csdn.net

Um desenvolvedor que trabalha discretamente em uma pequena empresa recentemente começou a aprender Unity sozinho por meio de hobbies. Em seu tempo livre, ele grava e compartilha enquanto aprende. Apoiar-se nos ombros de gigantes e aprender com as experiências de meus antecessores sempre será um benefício me muito. Ajude e inspire! PHP é trabalho, Unidade é vida! Se você encontrar algum problema, também pode comentar e me enviar uma mensagem privada. Embora eu possa não conhecer alguns dos problemas, verificarei as informações de todas as partes e tentarei dar as melhores sugestões. Espero ajudar mais pessoas que querem aprender programação., incentivem-se mutuamente ~

Insira a descrição da imagem aqui

Acho que você gosta

Origin blog.csdn.net/qq_36303853/article/details/135039078
Recomendado
Clasificación