‫Olá e bem-vindo de volta.
‫Agora temos movimento para o --, mas não estamos girando a parte superior do --, que estamos chamando
‫de torre.
‫Gostaríamos de poder fazer isso usando nosso mouse.
‫Agora, dê uma olhada no que está acontecendo aqui.
‫Enquanto estou movendo o cursor do mouse pelo mundo, estou recebendo esta esfera vermelha.
‫Esta é uma esfera de depuração que estou desenhando no espaço 3D.
‫Agora observe enquanto eu me movo contra uma parede, essa esfera se move contra a superfície da parede.
‫Então, onde quer que meu cursor do mouse esteja se movendo, estou tendo esse medo que corresponde a qualquer objeto que
‫estou atingindo com base na localização do meu cursor.
‫E isso será útil para nós, para que possamos ter um local no espaço para o qual possamos girar
‫nossa torre.
‫Agora, para fazer isso, existem algumas funções que precisamos no controlador, então temos que acessar essas
‫funções no controlador.
‫E neste vídeo vamos trabalhar na configuração disso e também vamos discutir como
‫isso envolverá um conceito conhecido como elenco.
‫Agora, a razão pela qual queremos o controlador é porque existem funções no controlador que nos permitem
‫obter o resultado do acerto sob o cursor.
‫Agora estamos falando sobre o cursor do mouse.
‫Então digamos que esta é a nossa tela e aqui está o nosso cursor do mouse.
‫E o ponto na ponta do cursor corresponde a um local na tela.
‫Agora, se movermos o cursor, nosso objetivo é que a parte da torre do nosso tanque, a
‫parte superior da nossa malha, gire para que fique voltada para a direção desse cursor.
‫Agora, se movermos o cursor, há uma função no controlador que podemos usar para obter
‫a localização correspondente a esse cursor.
‫Se fôssemos desenhar uma linha reta da câmera em direção ao cursor e acertar algum
‫objeto no mundo, podemos obter esse local e usar esse local para definir a rotação da torre do tanque.
‫Deixe-me mostrar o que quero dizer.
‫Agora, para obter esse local de acerto correspondente ao nosso cursor, precisamos usar o controlador.
‫Agora, vamos falar sobre o controlador por um breve momento.
‫Digamos que temos nosso peão no mundo.
‫Um peão terá um controlador.
‫Este é um objeto invisível que está associado ao peão.
‫Agora, para o nosso peão, nosso controle terá o controle de jogador tipo A e no
‫início do jogo, o controle terá o peão.
‫É por isso que podemos ver do ponto de vista da câmera que pertence ao nosso tanque de peões.
‫Agora podemos acessar este controlador.
‫Nossa classe tank herda uma função chamada Get Controller.
‫É herdado da classe --.
‫Então, o que gostaríamos de fazer é pegar esse controlador e armazená-lo em uma variável para que possamos usá-lo para
‫acessar a função que precisamos para obter o resultado da ocorrência sob o cursor.
‫Então vamos nos preparar para isso.
‫Agora estou aqui na classe tanque e o lugar que precisamos para acessar nosso controle é começar a jogar.
‫Se fizermos isso no construtor, será muito cedo e talvez ainda não tenhamos um controlador válido.
‫Então, vamos precisar da função de início de jogo aqui na classe tanque.
‫Agora temos aqui na classe base pong e até agora não estamos realmente usando begin play na classe
‫base pong.
‫Então, o que eu gostaria de fazer é movê-lo para a classe tanque.
‫Então, vou destacar começar a jogar, incluindo o comentário e a seção protegida aqui e
‫vou simplesmente cortá-la.
‫E então, de volta ao estágio do tanque, vou colá-lo.
‫Vamos adicionar esta seção protegida aqui logo acima da seção privada com o início da reprodução dentro.
‫Agora removemos o Begin Play do peão base.
‫Não o temos mais aqui, mas também precisamos removê-lo do cpp da base pond.
‫Aqui está.
‫Podemos ir em frente e excluí-lo aqui e agora o declaramos aqui no tanque H, mas também
‫precisamos defini-lo no tanque CPP.
‫Então, vou definir a função logo abaixo do componente de entrada do player de configuração.
‫Portanto, será void start play sem parâmetros de entrada.
‫Há o corpo da função e também precisamos de um tanque pré-fixando o nome da função.
‫Agora sabemos que é importante fazer call super big em jogo.
‫Dessa forma, qualquer funcionalidade na função begin play e qualquer uma das classes pai ainda serão
‫chamadas.
‫Então aqui nós começamos o jogo.
‫É aqui que podemos obter nosso controlador e armazená-lo em uma variável.
‫Então vamos voltar ao Tank H e criar uma variável.
‫Agora isso será privado e eu vou colocá-lo aqui na parte inferior
‫da seção privada e será um tipo de ponteiro de controlador de jogador e podemos chamar esse controlador de jogador ref.
‫Esta será nossa referência ao controlador do player.
‫Agora não estamos falando de uma referência C++.
‫Isso ainda é apenas um ponteiro, mas vamos usar isso para nos referirmos ao controlador do player.
‫Então agora temos uma variável player controller ref do tipo A player controller e estamos prontos para
‫armazenar o controlador neste ponteiro.
‫Então vamos voltar ao Tank Dot CP aqui e começar a jogar e tentar fazer isso.
‫Então.
‫O que vou fazer é dizer player, controller, ref equals e vou tentar chamar get controller.
‫Agora pegue o controlador, como mencionei, está na classe --.
‫Vamos clicar com o botão direito e ir para a definição e notar que esta função retorna um controlador A.
‫Agora nossa variável é do tipo A player controller, não um controller.
‫Então, o que estamos tentando fazer aqui é pegar o valor de retorno de get controller, que é do tipo
‫de ponteiro de controlador e estamos tentando armazená-lo em um ponteiro de controlador de jogador A.
‫Observe que vemos o rabisco vermelho aqui.
‫Diz um valor do tipo.
‫Um ponteiro de controlador não pode ser atribuído a uma entidade do tipo.
‫Um controlador de jogador.
‫Estamos recebendo um erro.
‫Vamos dar uma olhada aqui na documentação de um controlador.
‫Dê uma olhada.
‫Aqui está um controlador.
‫E diz herança, hierarquia.
‫E abaixo de um controlador, vemos um controlador e um controlador de jogador.
‫Isso significa que um controlador de jogador é uma classe filha de um controlador.
‫Agora, em C++, não podemos ter um ponteiro de tipo.
‫Um controlador de jogador armazena o valor do endereço de um controlador A.
‫Um controlador é o tipo pai.
‫Um controlador de jogador é do tipo filho.
‫Você não pode pegar um objeto do tipo pai e armazená-lo em um ponteiro do tipo filho.
‫Então, como vamos contornar isso?
‫Então aqui está o nosso problema.
‫A função get controller retorna o endereço de um controller A.
‫Agora, isso é algo que poderíamos armazenar em um ponteiro de controlador A, mas não podemos armazená-lo em um ponteiro de controlador
‫de jogador A.
‫O engraçado, porém, é que o objeto retornado por get controller é na verdade um player controller.
‫Portanto, temos esse endereço na forma de um ponteiro de controlador A e sabemos que ele armazena um controlador de player, mas se
‫o tivermos na forma de um controlador A, não podemos acessar a função de que precisamos porque ela
‫existe em um controlador de player .
‫A função é chamada obter resultado de acerto sob o cursor.
‫Agora, se tivermos um valor de ponteiro de controlador do tipo A e tentarmos obter essa função que existe
‫em um controlador de jogador, não conseguiremos fazê-lo.
‫Receberemos um erro de compilação.
‫Então, como sabemos que o próprio objeto é um controlador de jogador, ele é armazenado apenas em um ponteiro de controlador A.
‫Como contornamos esse problema?
‫A resposta é que temos que lançar.
‫Sabemos que um controlador é a classe pai e um controlador de jogador é a classe filha.
‫E sabemos que não podemos ter um controlador A armazenado em um ponteiro de controlador de jogador A.
‫Sabemos que podemos fazer o contrário e ter um armazenamento de ponteiro de controlador A, um objeto de um controlador
‫de jogador.
‫Na verdade, é isso que estamos vendo quando chamamos get controller, ele retorna um ponteiro de controlador A que aponta
‫para um controlador de jogador A.
‫Portanto, se tivermos um valor de ponteiro de controlador do tipo A, podemos usar uma função especial chamada cast para converter
‫o tipo do ponteiro em um ponteiro de controlador de jogador A.
‫Assim, a conversão altera o tipo de um ponteiro para outro tipo de ponteiro, desde que o próprio objeto seja o tipo para
‫o qual estamos tentando converter.
‫Agora, se tentarmos converter para um tipo inválido, por exemplo, temos um ponteiro de controlador A apontando para
‫um objeto controlador de jogador.
‫Se tentarmos converter para dizer um caractere, a função cast retorna null e dizemos que falhamos na
‫conversão.
‫Portanto, a função de conversão se parece com isso.
‫É um modelo como criar um subobjeto padrão.
‫Esta função de modelo irá se adaptar ao tipo escolhido e nesta função, o tipo que passamos é o tipo
‫que estamos lançando também.
‫Então passamos esse tipo.
‫Gostaríamos de lançar dois dentro dos colchetes angulares e passamos o ponteiro que gostaríamos de lançar
‫entre parênteses.
‫Aqui está um exemplo.
‫Digamos que gostaríamos de transmitir para um controlador de jogador e um ponteiro do tipo de controlador tipo A.
‫Passamos o ponteiro para os parênteses e o tipo para o qual estamos convertendo nos colchetes angulares.
‫E o que é retornado é um valor do tipo A ponteiro do controlador do jogador.
‫Então aqui está a chamada de função onde estamos passando o tipo entre colchetes angulares e o
‫valor do ponteiro do controlador A que retornamos do controlador get pode ir entre parênteses.
‫Portanto, precisamos lançar esse valor que estamos retornando do controlador get.
‫Esse vai ser o seu desafio.
‫Portanto, em Begin Play, use a função get controller e passe esse valor para a função cast e transmita para
‫um controlador de jogador.
‫E então você pode armazenar o resultado em nosso ponteiro ref do controlador do player, que é do tipo A ponteiro do controlador
‫do player.
‫Pause o vídeo e execute o elenco.
‫OK.
‫Então nós temos quase todo o trabalho feito aqui, só precisamos lançar.
‫Então, o que vamos fazer é chamar a função cast, que tem colchetes angulares e parênteses.
‫E o que vai entre parênteses é o valor que gostaríamos de lançar.
‫Agora get controller retorna um ponteiro do tipo A controller.
‫Vou mover isso aqui para os parênteses.
‫E o tipo para o qual estamos lançando é um controlador de jogador.
‫Então, novamente estamos pegando o valor retornado por get comptroller.
‫Isso retorna um ponteiro de controlador ou um endereço.
‫Então estamos usando o cast para lançá-lo para um controlador de jogador A.
‫Sabemos que o objeto retornado pelo controlador de portão é um objeto controlador de jogador A armazenado em um ponteiro
‫de controlador A.
‫Então, depois de lançarmos isso, o que é retornado é um ponteiro do controlador de jogador tipo A.
‫Então, estamos armazenando isso no controlador do player ref.
‫Agora que temos acesso ao controlador na forma de um ponteiro de controlador de jogador A, podemos acessar a função
‫que precisamos para obter o resultado de acerto do rastreamento sob o cursor.
‫Então, em resumo, usamos o controlador get para obter acesso ao controlador.
‫Também usamos a função cast para converter do ponteiro do controlador do tipo A para o ponteiro do controlador do jogador do tipo
‫A.
‫Agora podemos acessar a função que precisamos, que é obter resultados de acertos sob o cursor que existe na classe de
‫controlador de jogador A.
‫Então vamos começar a usar esta função no próximo vídeo.
‫Vejo você em breve.