Partage
  • Partager sur Facebook
  • Partager sur Twitter

[UE4] UMaterialInstanceDynamic crash

22 octobre 2016 à 18:37:23

Bonjour,

J'essaie de faire une arme capable de changer de mode, ce qui va influer l'action de ses projectiles. Ca marche bien, mais j'ai voulu faire ne sorte qu'elle change de couleur en fonction de son "mode", et je coince.

J'ai créé un "WeaponMaterial" et j'essaie de l'appliquer à une Material Instance Dynamic, mais ça crash :(

 // Fill out your copyright notice in the Description page of Project Settings.

#pragma once

#include "GameFramework/Actor.h"
#include "Projectile.h"
#include "Weapon.generated.h"


UCLASS()
class DOWNSTAIRS_API AWeapon : public AActor
{
	GENERATED_BODY()
	
public:

	// Sets default values for this actor's properties
	AWeapon();

	// Called when the game starts or when spawned
	virtual void BeginPlay() override;
	
	// Called every frame
	virtual void Tick( float DeltaSeconds ) override;

	void fire(FRotator launchDir);

	void setMode(int m);

	void changeMode(float offset);

	void setHero(class AHero *h) {
		hero = h;
	}

	class AHero *parentHero() {
		return hero;
	}

private:

	UFUNCTION()
	void onHit(AActor* SelfActor, AActor* OtherActor, FVector NormalImpulse, const FHitResult& Hit);
	
	UStaticMeshComponent *look;

	UPROPERTY()
	UMaterialInstanceDynamic *material;

	UPROPERTY(EditAnywhere)
	int mode;

	class AHero *hero;
};
// Fill out your copyright notice in the Description page of Project Settings.

#include "DownStairs.h"
#include "Hero.h"
#include "Weapon.h"


// Sets default values
AWeapon::AWeapon()
{
 	// Set this actor to call Tick() every frame.  You can turn this off to improve performance if you don't need it.
	PrimaryActorTick.bCanEverTick = true;

	look = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("Look"));
	static ConstructorHelpers::FObjectFinder<UStaticMesh> asset(TEXT("StaticMesh'/Game/Objects/weapon.weapon'"));
	if (asset.Succeeded())
	{
		look->SetStaticMesh(asset.Object);
		look->SetRelativeLocation(FVector(0.0f, 0.0f, 0.0f));
		//look->SetWorldScale3D(FVector(0.2f));
	}
	look->SetupAttachment(RootComponent);

	static ConstructorHelpers::FObjectFinder<UMaterial> m(TEXT("Material'/Game/Materials/GunMaterial.GunMaterial'"));
	if (m.Object != NULL)
	{
		material = look->CreateDynamicMaterialInstance(0, m.Object);
		//material = UMaterialInstanceDynamic::Create((UMaterial*)m.Object, look);
		setMode(0);
		look->SetMaterial(0, material);
	}


	OnActorHit.AddDynamic(this, &AWeapon::onHit);
}

// Called when the game starts or when spawned
void AWeapon::BeginPlay()
{
	Super::BeginPlay();

	setMode(mode);
}

// Called every frame
void AWeapon::Tick( float DeltaTime )
{
	Super::Tick( DeltaTime );

}

void AWeapon::fire(FRotator launchDir)
{
	UWorld *w = GetWorld();
	if (w)
	{
		FVector location;
		FRotator rotation;
		GetActorEyesViewPoint(location, rotation);
		location += parentHero()->GetActorRightVector() * -25.0f;

		FActorSpawnParameters SpawnParams;
		SpawnParams.Owner = this;
		SpawnParams.Instigator = Instigator;

		AProjectile* const Projectile = w->SpawnActor<AProjectile>(AProjectile::StaticClass(), location, rotation, SpawnParams);
		if (Projectile)
		{
			Projectile->setMode(mode);
			Projectile->setDamagesTargets(false, true);
			Projectile->setGun(this);
			Projectile->InitVelocity(launchDir.Vector());
		}
	}
}

void AWeapon::setMode(int m)
{
	mode = m;

	switch (m)
	{
		case 0:
			material->SetVectorParameterValue("Color", FLinearColor(1.0f, 0.0f, 0.0f));
		break;

		case 1:
			material->SetVectorParameterValue("Color", FLinearColor(0.0f, 1.0f, 0.0f));
		break;

		case 2:
			material->SetVectorParameterValue("Color", FLinearColor(0.0f, 0.0f, 1.0f));
		break;

		case 3:
			material->SetVectorParameterValue("Color", FLinearColor(1.0f, 1.0f, 0.0f));
		break;
	}
}

void AWeapon::changeMode(float offset)
{
	int m = mode + (int)FMath::Clamp(offset, -1.0f, 1.0f);
	if (m >= gunModeCount)
		m = 0;
	else if (m < 0)
		m = gunModeCount - 1;

	setMode(m);
}

void AWeapon::onHit(AActor* SelfActor, AActor* OtherActor, FVector NormalImpulse, const FHitResult& Hit)
{
	if (OtherActor && (OtherActor != this) && SelfActor)
	{
		AHero *hero = Cast<AHero>(OtherActor);

		if (hero) // Is an hero
		{
			AttachToComponent(hero->getArms(), FAttachmentTransformRules::SnapToTargetIncludingScale, FName("weapon_r"));
			hero->putWeapon(this);
			//getComponent()->AddImpulseAtLocation(NormalImpulse, Hit.ImpactPoint);
		}
	}
}




  • Partager sur Facebook
  • Partager sur Twitter
Codeur en herbe en C++ et Html/Css/JavaScript. Passez voir la chaîne Computer Scientists
19 juin 2023 à 2:56:27 - Message modéré pour le motif suivant : Message complètement hors sujet


20 juin 2023 à 18:52:29

Bonjour,

Déterrage

Citation des règles générales du forum :

Avant de poster un message, vérifiez la date du sujet dans lequel vous comptiez intervenir.

Si le dernier message sur le sujet date de plus de deux mois, mieux vaut ne pas répondre.
En effet, le déterrage d'un sujet nuit au bon fonctionnement du forum, et l'informatique pouvant grandement changer en quelques mois il n'est donc que rarement pertinent de déterrer un vieux sujet.

Au lieu de déterrer un sujet il est préférable :

  • soit de contacter directement le membre voulu par messagerie privée en cliquant sur son pseudonyme pour accéder à sa page profil, puis sur le lien "Ecrire un message"
  • soit de créer un nouveau sujet décrivant votre propre contexte
  • ne pas répondre à un déterrage et le signaler à la modération

Je ferme ce sujet. En cas de désaccord, me contacter par MP.

  • Partager sur Facebook
  • Partager sur Twitter