Форум программистов, компьютерный форум, киберфорум
Unreal Engine
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.60/15: Рейтинг темы: голосов - 15, средняя оценка - 4.60
2 / 2 / 0
Регистрация: 16.01.2022
Сообщений: 59

Метод, показывающий, что кнопка нажата

03.06.2022, 11:38. Показов 3901. Ответов 17
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Всем привет, делаю шутер, чтобы реализовать автоматическую стрельбу, мне нужно знать что кнопка стрелять нажата. Какой метод в ue 4 с++ за это отвечает?
0
Лучшие ответы (1)
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
03.06.2022, 11:38
Ответы с готовыми решениями:

Как определить нажата ли кнопка
У меня есть игра пол мобилы, но у неё есть один минус, каждый раз чтобы двинуться хотя-бы на пиксель, нужно нажимать на кнопку...

Выполнение функции пока нажата UI кнопка
Здравствуйте. Как сделать так, что бы функция к примеру перемежение, выполнялась всегда пока нажата UI кнопка. Спасибо.

Как проверить нажата ли UI кнопка в юнити?
Потом если она нажата выполнить действие

17
Модератор
Эксперт Java
 Аватар для alecss131
2835 / 1344 / 403
Регистрация: 11.08.2017
Сообщений: 4,297
Записей в блоге: 2
03.06.2022, 11:42
Цитата Сообщение от flysuperman Посмотреть сообщение
чтобы реализовать автоматическую стрельбу
обычно это делают через таймеры, при первом нажатии таймер запускают, а при отпускании останавливают
0
2 / 2 / 0
Регистрация: 16.01.2022
Сообщений: 59
03.06.2022, 12:39  [ТС]
Таймер я сделал, срабатывает playerinputcomponent->bindAxis, запускается функция стрельбы и таймер, а чтоб его остановить метод должен знать, что кнопка отпущена, я не могу найти эту функцию
0
Модератор
Эксперт Java
 Аватар для alecss131
2835 / 1344 / 403
Регистрация: 11.08.2017
Сообщений: 4,297
Записей в блоге: 2
03.06.2022, 12:59
Цитата Сообщение от flysuperman Посмотреть сообщение
playerinputcomponent->bindAxis
Надо bindAction, чтобы событие было только один раз при нажатии
Например прыжок
C++
1
2
    PlayerInputComponent->BindAction("Run", IE_Pressed, this, &AMyCharacter::Run);
    PlayerInputComponent->BindAction("Run", IE_Released, this, &AMyCharacter::StopRunning);
Только вместо AMyCharacter::Run повесить метод запуска таймера стрельбы, а вместо AMyCharacter::StopRunning метод остановки таймера
0
2 / 2 / 0
Регистрация: 16.01.2022
Сообщений: 59
03.06.2022, 13:06  [ТС]
Это немного не то, тут я нажал и отпустил кнопку и стрельба идет по таймеру, опять нажал и отпустил, стрельба окончена, а мне нужно, чтоб я задал кнопку идет стрельба с интервалом между выстрелами, отпустил, стрельба прекращена

Добавлено через 25 секунд
Зажал
0
Модератор
Эксперт Java
 Аватар для alecss131
2835 / 1344 / 403
Регистрация: 11.08.2017
Сообщений: 4,297
Записей в блоге: 2
03.06.2022, 13:07
Цитата Сообщение от flysuperman Посмотреть сообщение
Это немного не то, тут я нажал и отпустил кнопку и стрельба идет по таймеру, опять нажал и отпустил, стрельба окончена, а мне нужно, чтоб я задал кнопку идет стрельба с интервалом между выстрелами, отпустил, стрельба прекращена
Нет, это работает как раз таки как я и говорю, нажал стреляет, отпустил перестает.

Добавлено через 42 секунды
Отпускание клавиши прекращает стрельбу остановкой таймера
0
2 / 2 / 0
Регистрация: 16.01.2022
Сообщений: 59
03.06.2022, 13:16  [ТС]
Спасибо, попробую, а сами функции чисто вкделают какую то переменную true или возвращают true?
0
Модератор
Эксперт Java
 Аватар для alecss131
2835 / 1344 / 403
Регистрация: 11.08.2017
Сообщений: 4,297
Записей в блоге: 2
03.06.2022, 13:25
Нет это методы как и у всех BindAction имеют прототип void name(void);
0
2 / 2 / 0
Регистрация: 16.01.2022
Сообщений: 59
03.06.2022, 13:39  [ТС]
Тогда я не понимаю что в них писать, у меня метод fire()
Если патронов больше 0,
То выстрел и тд
Обнуление таймера
Запуск таймера true
И в tick
Если таймер >1 то опять вызов fire(), отключение таймера
А там проверка, обнуление таймера и запуск
0
Модератор
Эксперт Java
 Аватар для alecss131
2835 / 1344 / 403
Регистрация: 11.08.2017
Сообщений: 4,297
Записей в блоге: 2
03.06.2022, 13:45
В тике ничего не надо писать, количество патронов должно быть у класса оружия. Можно у класса оружия сделать метод есть ли патроны и в методе его вызывать и запускать таймер когда они есть.
0
2 / 2 / 0
Регистрация: 16.01.2022
Сообщений: 59
03.06.2022, 13:52  [ТС]
В тике реализован чисто таймер, я не нашел где взять и сделал забыл уже название, я щас не дома, типа переменная из world которая прибавляется каждую секунду... Суть моего вопроса в том, что я должен дать понять программе что кнопка надата или отпущена, например в блюпринтах для events уже есть ноды is pressed, is released, что что такое я хотел, код могу выложить вечером или завтра(
0
Модератор
Эксперт Java
 Аватар для alecss131
2835 / 1344 / 403
Регистрация: 11.08.2017
Сообщений: 4,297
Записей в блоге: 2
04.06.2022, 12:05
Лучший ответ Сообщение было отмечено flysuperman как решение

Решение

Вот пример использования таймера и стрельбы
Заголовок
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
// Fill out your copyright notice in the Description page of Project Settings.
 
#pragma once
 
#include "CoreMinimal.h"
#include "GameFramework/Character.h"
#include "MyCharacter.generated.h"
 
UCLASS()
class FORALLCPP_API AMyCharacter : public ACharacter
{
    GENERATED_BODY()
 
public:
    // Sets default values for this character's properties
    AMyCharacter();
 
protected:
    // Called when the game starts or when spawned
    virtual void BeginPlay() override;
 
public: 
    // Called every frame
    virtual void Tick(float DeltaTime) override;
 
    // Called to bind functionality to input
    virtual void SetupPlayerInputComponent(class UInputComponent* PlayerInputComponent) override;
 
private:
    void MoveForward(float Axis);
    void MoveRight(float Axis);
    void Fire();
    void StopFire();
    void DoFire();
    FTimerHandle TimerHandle;
 
};
Реализация
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
// Fill out your copyright notice in the Description page of Project Settings.
 
 
#include "MyCharacter.h"
#include "Components/CapsuleComponent.h"
 
DECLARE_LOG_CATEGORY_CLASS(MyLog, All, All)
 
// Sets default values
AMyCharacter::AMyCharacter()
{
    // Set this character to call Tick() every frame.  You can turn this off to improve performance if you don't need it.
    PrimaryActorTick.bCanEverTick = true;
    GetCapsuleComponent()->SetCapsuleSize(40.0f, 90.0f);
}
 
// Called when the game starts or when spawned
void AMyCharacter::BeginPlay()
{
    Super::BeginPlay();
    
}
 
// Called every frame
void AMyCharacter::Tick(float DeltaTime)
{
    Super::Tick(DeltaTime);
 
}
 
// Called to bind functionality to input
void AMyCharacter::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent)
{
    //Super::SetupPlayerInputComponent(PlayerInputComponent);
    PlayerInputComponent->BindAction("Jump", IE_Pressed, this, &ACharacter::Jump);
    PlayerInputComponent->BindAction("Jump", IE_Released, this, &ACharacter::StopJumping);
    PlayerInputComponent->BindAxis("MoveForward", this, &AMyCharacter::MoveForward);
    PlayerInputComponent->BindAxis("MoveRight", this, &AMyCharacter::MoveRight);
    PlayerInputComponent->BindAxis("Turn", this, &APawn::AddControllerYawInput);
    PlayerInputComponent->BindAxis("LookUp", this, &APawn::AddControllerPitchInput);
    PlayerInputComponent->BindAction("Fire", IE_Pressed, this, &AMyCharacter::Fire);
    PlayerInputComponent->BindAction("Fire", IE_Released, this, &AMyCharacter::StopFire);
}
 
void AMyCharacter::MoveForward(float Axis)
{
    AddMovementInput(GetActorForwardVector(), Axis);
}
 
void AMyCharacter::MoveRight(float Axis)
{
    AddMovementInput(GetActorRightVector(), Axis);
}
 
void AMyCharacter::Fire()
{
    UE_LOG(MyLog, Display, TEXT("Fire Started"))
    GetWorldTimerManager().SetTimer(TimerHandle, this, &AMyCharacter::DoFire, 1.0f, true);
}
 
void AMyCharacter::StopFire()
{
    UE_LOG(MyLog, Display, TEXT("Fire Stopped"))
    GetWorldTimerManager().ClearTimer(TimerHandle);
}
 
void AMyCharacter::DoFire()
{
    UE_LOG(MyLog, Display, TEXT("Piy"))
}
Настройки кнопок

Результат, я просто вывожу в консоль надпись, с частотой 1 секунда, пока нажата кнопка огня, то есть левая кнопка мыши, при этом еще выводятся сообщения о начале/окончании стрельбы
0
2 / 2 / 0
Регистрация: 16.01.2022
Сообщений: 59
04.06.2022, 21:10  [ТС]
Спасибо, теперь почти понятно, я пользовался этим таймером, чтоб патроны зарядились после анимации перезарядки, но я так и не понял как он работает. Очистка таймера будет после того как пройдет секунда? Или всю эту секунду будут выстрелы? Или между выстрелами интервал в секунду, разъясни пожалуйста
0
Модератор
Эксперт Java
 Аватар для alecss131
2835 / 1344 / 403
Регистрация: 11.08.2017
Сообщений: 4,297
Записей в блоге: 2
04.06.2022, 21:25
Можно поменять
C++
1
GetWorldTimerManager().SetTimer(TimerHandle, this, &AMyCharacter::DoFire, 1.0f, true);
на
C++
1
GetWorldTimerManager().SetTimer(TimerHandle, this, &AMyCharacter::DoFire, 1.0f, true, 0.0f);
и тогда не будет паузы перед первым срабатыванием.
this это объект у которого вызывается метод передаваемые следующим аргументом
1.0f частота срабатывания, в данном случае 1 секунда
true означает что таймер зациклен, то есть работает пока не будет очищен
0.0f задержка перед первым срабатыванием, по умолчанию равна частоте срабатывания, то есть при первом варианте он первый раз сработает только спустя секунду от активации.
Таймер работает с указанной частотой (1 секунда) и если зациклен то пока не очистить. Поэтому я назначил очистку таймера на отпускание кнопки огня. Сам не очищается если зациклен.
Таймер обычно делается для повторяющихся событий, для однократного вызова куда реже.
Вот тут
C++
1
PlayerInputComponent->BindAction("Fire", IE_Released, this, &AMyCharacter::StopFire);
вторым параметром IE_Pressed событие нажатия, а IE_Released - отпускания, есть только у BindAction
0
2 / 2 / 0
Регистрация: 16.01.2022
Сообщений: 59
05.06.2022, 11:31  [ТС]
Спасибо большое за подробный ответ, теперь все понятно, хорошо, что есть такие люди, как ты, которые помогут, а не тупо забьют.
0
2 / 2 / 0
Регистрация: 16.01.2022
Сообщений: 59
05.06.2022, 22:29  [ТС]
Цитата Сообщение от alecss131 Посмотреть сообщение
а IE_Released - отпускания, есть только у BindAction
этот момент я и не заметил что кнопка отпущена, думаю как он сам переключает и знает, что кнопка отпущена)

Добавлено через 4 часа 0 минут
Привет еще раз, сделал твои маневры, все получилось, но теперь не могу сделать та, чтоб когда патроны кончались после щелчка автоматически перезарядка началась, он щелкает и все, помоги пожалуйста, вот код

FPS_Character.h
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
#pragma once
 
#include "CoreMinimal.h"
#include "PR5Character.h"
#include "FPS_Character.generated.h"
 
/**
 * 
 */
class AAK_Weapon;
class UAnimMontage;
 
UCLASS()
class PR5_API AFPS_Character : public APR5Character
{
    GENERATED_BODY()
public:
 
    // Если он не установлен, то монстр использует просто рукопашную атаку
    UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = Parametrs)
        UClass* curret_weapon;
    // Экземпляр MeleeWeapon (устанавливается если персонаж использует
    // оружие для рукопашной схватки)
    
        AAK_Weapon* AK_Weapon;
 
    UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = Animations)
        UAnimMontage* arms_AK_Fire;
 
    UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = Animations)
        UAnimMontage* arms_AK_Reload;
 
 
 
    bool IsReload{};
    bool Reloaded{};
 
     AFPS_Character(const FObjectInitializer& ObjectInitializer);
    /** Called for forwards/backward input */
    void MoveForward(float Value);
 
    /** Called for side to side input */
    void MoveRight(float Value);
 
    virtual void PostInitializeComponents() override;
 
    virtual float TakeDamage(float Damage, struct FDamageEvent const&
        DamageEvent, AController* EventInstigator, AActor* DamageCauser);
 
    virtual void SetupPlayerInputComponent(class UInputComponent* PlayerInputComponent);
 
 
    
    UFUNCTION(BlueprintCallable, Category = ray_traccing)
     void fire();
     void reload();
     void StopFire();
     void DoFire();
     FTimerHandle TimerHandle;
 
     // Called every frame
     virtual void Tick(float DeltaTime) override;
 
    
};

FPS_Character.сpp

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
#include "AK_Weapon.h"
#include "FPS_Character.h"
#include "Animation/AnimMontage.h"
 
 
 
AFPS_Character::AFPS_Character(const FObjectInitializer& ObjectInitializer) :
Super(ObjectInitializer)
{
    // Don't rotate when the controller rotates. Let that just affect the camera.
    bUseControllerRotationPitch = false;
    bUseControllerRotationYaw = true;
    bUseControllerRotationRoll = true;
    IsReload = false;
    
 
}
 
 
void AFPS_Character::PostInitializeComponents()
{
    Super::PostInitializeComponents();
 
    // создаём экземпляр оружия, если блупринт был выбран
    if (curret_weapon)
    {
 
        AK_Weapon = GetWorld()->SpawnActor<AAK_Weapon>(curret_weapon, FVector(),
            FRotator());
 
 
        if (AK_Weapon)
        {
            AK_Weapon->AttachToComponent(GetMesh(), FAttachmentTransformRules(EAttachmentRule::SnapToTarget, true), "Palm_R");
 
 
 
 
            //const USkeletalMeshSocket* socket = GetMesh()->GetSocketByName("ik_hand_r");
            // убедитесь, что используете верное
            // имя сокета!
            //socket->atta    AttachActor(MeleeWeapon, GetMesh());
 
        }
 
    }
}
 
void AFPS_Character::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent)
{
    Super::SetupPlayerInputComponent(PlayerInputComponent);
 
    PlayerInputComponent->BindAction("Attack", IE_Pressed, this, &AFPS_Character::fire);
    PlayerInputComponent->BindAction("Attack", IE_Released, this, &AFPS_Character::StopFire);
    PlayerInputComponent->BindAction("Reload", IE_Pressed, this, &AFPS_Character::reload);
    
    
    
}
 
void AFPS_Character::fire()
{
    GetWorldTimerManager().SetTimer(TimerHandle, this, &AFPS_Character::DoFire, 0.15f, true, 0.0f);
    
}
 
void AFPS_Character::reload()
{
    
    if (AK_Weapon->AMMO_COUNT < AK_Weapon->MAX_AMMO_CLIP && AK_Weapon->EQUIP_MAX_AMMO !=0 )
    {
        
        IsReload = true;
    }
    else
    {
        return;
    }
        if (AK_Weapon && arms_AK_Reload && IsReload)
        {
            AK_Weapon->reload();
            PlayAnimMontage(arms_AK_Reload);
 
        
    }
}
 
 
 
 
 
 
void AFPS_Character::MoveForward(float Value)
{
    if (Controller && Value)
    {
        FVector fwd = GetActorForwardVector();
        // мы вызываем AddMovementInput, чтобы собственно двигать
        // игрока `суммой` в направлениях `fwd`
        AddMovementInput(fwd, Value);
    }
}
 
 
void AFPS_Character::MoveRight(float Value)
{
    Super::MoveRight(Value);
 
    if (Controller && Value)
    {
        FVector rdt = GetActorRightVector();
        // мы вызываем AddMovementInput, чтобы собственно двигать
        // игрока `суммой` в направлениях `fwd`
        AddMovementInput(rdt, Value);
    }
}
 
 
// Called every frame
void AFPS_Character::Tick(float DeltaTime)
{
    Super::Tick(DeltaTime);
    
 
 }
 
 
float AFPS_Character::TakeDamage(float Damage, struct FDamageEvent const&
    DamageEvent, AController* EventInstigator, AActor* DamageCauser)
{
    Super::TakeDamage(Damage,
        DamageEvent, EventInstigator, DamageCauser);
    GEngine->AddOnScreenDebugMessage(2, 625, FColor::Red, "Time= 5664646");
    Hp -= 5 * Damage;
    return 0;
}
 
 
 
void AFPS_Character::StopFire()
{
    
        GetWorldTimerManager().ClearTimer(TimerHandle);
}
 
void AFPS_Character::DoFire()
{
    if (AK_Weapon && arms_AK_Fire && !Reloaded)
    {
 
        AK_Weapon->fire();
        if (AK_Weapon->AMMO_COUNT != 0)
        {
            PlayAnimMontage(arms_AK_Fire);
        }
 
    }
}
BaseWeapon.h
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
#pragma once
 
#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "BaseWeapon.generated.h"
 
class USceneComponent;
class USoundBase;
class ATraser;
class AShell;
class UParticleSystemComponent;
class AFPS_Character;
 
UCLASS()
class PR5_API ABaseWeapon : public AActor
{
    GENERATED_BODY()
    
public: 
    // Sets default values for this actor's properties
    ABaseWeapon(const FObjectInitializer& ObjectInitializer);
            
        UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = Parametrs)
            float AttackDamage{};
        UPROPERTY(EditAnywhere, BlueprintReadWrite)
            USkeletalMeshComponent* Mesh1;
        UPROPERTY(EditAnywhere, BlueprintReadWrite)
            USceneComponent* scenecomp;
        UPROPERTY(EditAnywhere, BlueprintReadWrite)
            USceneComponent* scenecompShell;
        UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = Parametrs)
            float RELOAD_TIME;
        UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = Parametrs)
            float BULLET_SPRAY;
        UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = Parametrs)
            int32 AMMO_COUNT;
        UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = Parametrs)
            int32 MAX_AMMO;
        UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = Parametrs)
            int32 MAX_AMMO_CLIP;
        UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = Parametrs)
            int32 EQUIP_MAX_AMMO;
        UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = Animations)
            UAnimationAsset* animReload;
        UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = Animations)
            UAnimationAsset* animFire;
        UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = Sounds)
            USoundBase* FireSound;
        UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = Sounds)
            USoundBase* DryFireSound;
        UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = Parametrs)
            float waitToReloadTime;
        UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = Sounds)
        USoundAttenuation* soundat;//звук на расстоянии
        UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = Sounds)
            USoundConcurrency* soundConc;// звук вокруг цели
        UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = Parametrs)
            UClass* curret_Bullet;
        UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = Parametrs)
            UClass* curret_Shell;
 
        // Экземпляр MeleeWeapon (устанавливается если персонаж использует
        // оружие для рукопашной схватки)
                    ATraser* Bullet;
                    AShell* Shell;
                    
                    UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = Animations)
                        UParticleSystemComponent* decal;
                    
 
                    AFPS_Character* fps_avatar;
                    
 
virtual void PostInitializeComponents() override;
        int GetRandomNumber(int min, int max);
        float timer;
        bool startTimer;
        bool automaticTimer{};
        
        void AmmoCheck();
        UFUNCTION(BlueprintCallable, Category = ray_traccing)
        void fire();
        void reload();
        void reload_Bullets();
 
 
protected:
    // Called when the game starts or when spawned
    virtual void BeginPlay() override;
 
 
 
public: 
    // Called every frame
    virtual void Tick(float DeltaTime) override;
 
};
BaseWeapon.cpp

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
#include "FPS_Character.h"
#include "Components/SceneComponent.h"
#include "BaseWeapon.h"
#include "Kismet/GameplayStatics.h"
#include "Engine/World.h"
#include "Camera/CameraComponent.h"
#include "Components/AudioComponent.h"
#include <time.h>
#include "GameFramework/Pawn.h"
#include "Traser.h"
#include "DrawDebugHelpers.h"
#include "Shell.h"
#include "Particles/ParticleSystemComponent.h"
 
#include <stdlib.h>
 
// Sets default values
ABaseWeapon::ABaseWeapon(const FObjectInitializer& ObjectInitializer) :
    Super(ObjectInitializer)
{
    // 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;
    AttackDamage = 10;
    decal = ObjectInitializer.CreateDefaultSubobject<UParticleSystemComponent>(this, TEXT("Decal"));
    Mesh1 = ObjectInitializer.CreateDefaultSubobject <USkeletalMeshComponent>(this, TEXT("Mesh1"));
    RootComponent = Mesh1;
    scenecomp= ObjectInitializer.CreateDefaultSubobject <USceneComponent>(this, TEXT("scenecomp"));
    scenecompShell = ObjectInitializer.CreateDefaultSubobject <USceneComponent>(this, TEXT("scenecompSheel"));
    scenecompShell->AttachTo(RootComponent);
    scenecomp->AttachTo(RootComponent);
    decal->AttachTo(scenecomp);
    decal->Deactivate();
    waitToReloadTime = 1;
    timer = waitToReloadTime;
    startTimer = false;
    automaticTimer = false;
    fps_avatar = Cast<AFPS_Character>(fps_avatar);//каст на персоонажа
    
}
 
 
void ABaseWeapon::PostInitializeComponents()
{
    Super::PostInitializeComponents();
/*
    // создаём экземпляр оружия, если блупринт был выбран
    if (curret_Bullet)
    {
 
        Bullet = GetWorld()->SpawnActor<ATraser>(curret_Bullet, scenecomp->GetForwardVector(), scenecomp->GetComponentRotation());
 
 
*/
    }
 
 
 
 
void ABaseWeapon::AmmoCheck()
{
    AMMO_COUNT--; //убавляем 1 патрон
 
    //AFPS_Character* fps_avatar = Cast<AFPS_Character>(UGameplayStatics::GetPlayerPawn(GetWorld(), 0));//каст на персоонажа
 
    
    if (animFire)//если перезарядка невозможна и анимации инициализирована
    {
        Mesh1->PlayAnimation(animFire, false);
 
        
    }
 
    
}
 
// Called when the game starts or when spawned
void ABaseWeapon::BeginPlay()
{
    Super::BeginPlay();
    
}
 
void ABaseWeapon::fire()
{
    if (AMMO_COUNT > 0)
    {
        FHitResult OutHit;
        FVector Start = scenecomp->GetComponentLocation();
 
        // alternatively you can get the camera location
        // FVector Start = FirstPersonCameraComponent->GetComponentLocation();
 
        if (fps_avatar)
        {
            FVector ForwardVector = fps_avatar->GetFollowCamera()->GetForwardVector();
 
            FVector End = ((ForwardVector * 1000.f) + Start);
            FCollisionQueryParams CollisionParams;
 
 
            DrawDebugLine(GetWorld(), Start, End, FColor::Green, false, 1, 0, 1);
 
            if (GetWorld()->LineTraceSingleByChannel(OutHit, Start, End, ECC_Visibility, CollisionParams))
            {
                if (OutHit.bBlockingHit)
                {
                    if (GEngine) {
 
                        GEngine->AddOnScreenDebugMessage(-1, 1.f, FColor::Red, FString::Printf(TEXT("You are hitting: %s"), *OutHit.GetActor()->GetName()));
                        GEngine->AddOnScreenDebugMessage(-1, 1.f, FColor::Red, FString::Printf(TEXT("Impact Point: %s"), *OutHit.ImpactPoint.ToString()));
                        GEngine->AddOnScreenDebugMessage(-1, 1.f, FColor::Red, FString::Printf(TEXT("Normal Point: %s"), *OutHit.ImpactNormal.ToString()));
 
                    }
                }
            }
 
        }
 
 
 
        if (decal)
        {
            decal->Activate();
            decal->Deactivate();
        }
 
 
        if (curret_Bullet)
        {
            FActorSpawnParameters ActorSpawnParams;
            ActorSpawnParams.SpawnCollisionHandlingOverride = ESpawnActorCollisionHandlingMethod::AdjustIfPossibleButDontSpawnIfColliding;
            UWorld* const World = GetWorld();
 
            World->GetWorld()->SpawnActor<ATraser>(curret_Bullet, scenecomp->GetComponentLocation(), RootComponent->GetComponentRotation());
 
        }
 
        if (curret_Shell)
        {
            FActorSpawnParameters ActorSpawnParams;
            ActorSpawnParams.SpawnCollisionHandlingOverride = ESpawnActorCollisionHandlingMethod::AdjustIfPossibleButDontSpawnIfColliding;
            UWorld* const World = GetWorld();
 
            World->GetWorld()->SpawnActor<AShell>(curret_Shell, scenecompShell->GetComponentLocation(), RootComponent->GetComponentRotation());
        }
        AmmoCheck(); //если патронов в магазине Ю0 то стреляем
 
        if (FireSound != nullptr)
        {
 
            UGameplayStatics::PlaySoundAtLocation(this, FireSound, GetActorLocation(), GetRandomNumber(1, 2) + (GetRandomNumber(1, 5) * 0.3), 1, 0, soundat, soundConc);
 
        }
    }
 
 
            else
            {
 
                if (DryFireSound != nullptr)
                {
                    UGameplayStatics::PlaySoundAtLocation(this, DryFireSound, GetActorLocation());
                    
                }
                if (fps_avatar)
                {
                    FTimerHandle TimerHandle;
                    GetWorldTimerManager().SetTimer(TimerHandle, fps_avatar, &AFPS_Character::reload, 0.5f, false, 1.0f);
                }
                
                    
                
                
 
            }
        
    
 
}
    
 
    
    
 
 
void ABaseWeapon::reload()
{
    if (animReload )
    {
        
        Mesh1->PlayAnimation(animReload, false);
        float RepeatingCallsRemaining = 0;
        if (fps_avatar)
        {
            fps_avatar->Reloaded = true;
        }
        FTimerHandle MemberTimerHandle;
        GetWorldTimerManager().SetTimer(MemberTimerHandle, this, &ABaseWeapon::reload_Bullets, RELOAD_TIME, false, 2.0f); //таймер задержки типа delay
        //if (--RepeatingCallsRemaining <= 0)
        //{
            
            // MemberTimerHandle can now be reused for any other Timer.
        //}
        
    }
    
}
 
void ABaseWeapon::reload_Bullets()
{   
    if (AMMO_COUNT < MAX_AMMO_CLIP && EQUIP_MAX_AMMO >= MAX_AMMO_CLIP)
    {
        EQUIP_MAX_AMMO -= (MAX_AMMO_CLIP - AMMO_COUNT);
        AMMO_COUNT = MAX_AMMO_CLIP;
    }
    if (AMMO_COUNT < MAX_AMMO_CLIP && EQUIP_MAX_AMMO < MAX_AMMO_CLIP)
    {
        AMMO_COUNT += EQUIP_MAX_AMMO;
        EQUIP_MAX_AMMO = 0;
 
    }
 
 
    if (fps_avatar)
    {
        fps_avatar->Reloaded = false;
        //GetWorldTimerManager().ClearTimer(MemberTimerHandle);
    }
}
 
// Called every frame
void ABaseWeapon::Tick(float DeltaTime)
{
    
    
    Super::Tick(DeltaTime);
    GEngine->AddOnScreenDebugMessage(600,600 , FColor::Red, "curretAmmo= " + FString::FromInt(AMMO_COUNT));
    GEngine->AddOnScreenDebugMessage(605, 605, FColor::Red, "curretMaxAmmo= " + FString::FromInt(EQUIP_MAX_AMMO));
    GEngine->AddOnScreenDebugMessage(610, 609, FColor::Red, "Time= " + FString::SanitizeFloat(timer));
    if (AMMO_COUNT < 0)
    {
        AMMO_COUNT = 0;
    }
    
    
    
    if (EQUIP_MAX_AMMO > MAX_AMMO)
    {
        EQUIP_MAX_AMMO = MAX_AMMO;
    }
}
 
int ABaseWeapon::GetRandomNumber(int min, int max)
{
 
    srand(time(NULL));
    int num = min + rand() % (max - min + 1);
 
    return num;
 
}
0
Модератор
Эксперт Java
 Аватар для alecss131
2835 / 1344 / 403
Регистрация: 11.08.2017
Сообщений: 4,297
Записей в блоге: 2
06.06.2022, 11:10
flysuperman, 1 вопрос = 1 тема
А так если честно мне лень разбираться в коде, после беглого осмотра приходит совет почитать про Code Style движка, обратив особое внимание на Naming convention, а то куча разных стилей в 1 классе. А так же использование публичных полей через точку не есть хорошо, лучше сделать методы, например IsEmpty() или IsNeedReload()
0
2 / 2 / 0
Регистрация: 16.01.2022
Сообщений: 59
06.06.2022, 11:17  [ТС]
Спасибо, почитаю
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
06.06.2022, 11:17
Помогаю со студенческими работами здесь

Воспроизведение мелодии, пока кнопка нажата
В игре есть фоновая музыка, она играет постоянно, как сделать медодию включающуюся по кнопке? Надо нажали на кнопку звук мотора для...

Не определяет, что нажата кнопка
В общем, нужно, чтобы при нажатии на кнопку &quot;+&quot;, печаталось &quot;Нажат плюс&quot;, но почему - то выдает ошибку. Пишет вот что - error: ISO C++...

Проверка условия, что нажата определенная кнопка
Здравствуйте. Пишу программу, хочу указать условие - если нажали на конкретную кнопку, то выполняется такое то действие. Вопрос: есть ли...

Как делать что то пока нажата кнопка мыши?
Вечер добрый. Подскажите пожалуйста как делать какое то действие (рисовать) пока нажата левая кнопка мыши в JS?

Определить что кнопка не была нажата при выходе со страницы
(window.attachEvent || window.addEventListener)((window.attachEvent ? 'onbeforeunload' : 'beforeunload'), function(e) { // For &gt;=IE7,...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
18
Ответ Создать тему
Новые блоги и статьи
Access
VikBal 11.12.2025
Помогите пожалуйста !! Как объединить 2 одинаковые БД Access с разными данными.
Новый ноутбук
volvo 07.12.2025
Всем привет. По скидке в "черную пятницу" взял себе новый ноутбук Lenovo ThinkBook 16 G7 на Амазоне: Ryzen 5 7533HS 64 Gb DDR5 1Tb NVMe 16" Full HD Display Win11 Pro
Музыка, написанная Искусственным Интеллектом
volvo 04.12.2025
Всем привет. Некоторое время назад меня заинтересовало, что уже умеет ИИ в плане написания музыки для песен, и, собственно, исполнения этих самых песен. Стихов у нас много, уже вышли 4 книги, еще 3. . .
От async/await к виртуальным потокам в Python
IndentationError 23.11.2025
Армин Ронахер поставил под сомнение async/ await. Создатель Flask заявляет: цветные функции - провал, виртуальные потоки - решение. Не threading-динозавры, а новое поколение лёгких потоков. Откат?. . .
Поиск "дружественных имён" СОМ портов
Argus19 22.11.2025
Поиск "дружественных имён" СОМ портов На странице: https:/ / norseev. ru/ 2018/ 01/ 04/ comportlist_windows/ нашёл схожую тему. Там приведён код на С++, который показывает только имена СОМ портов, типа,. . .
Сколько Государство потратило денег на меня, обеспечивая инсулином.
Programma_Boinc 20.11.2025
Сколько Государство потратило денег на меня, обеспечивая инсулином. Вот решила сделать интересный приблизительный подсчет, сколько государство потратило на меня денег на покупку инсулинов. . . .
Ломающие изменения в C#.NStar Alpha
Etyuhibosecyu 20.11.2025
Уже можно не только тестировать, но и пользоваться C#. NStar - писать оконные приложения, содержащие надписи, кнопки, текстовые поля и даже изображения, например, моя игра "Три в ряд" написана на этом. . .
Мысли в слух
kumehtar 18.11.2025
Кстати, совсем недавно имел разговор на тему медитаций с людьми. И обнаружил, что они вообще не понимают что такое медитация и зачем она нужна. Самые базовые вещи. Для них это - когда просто люди. . .
Создание Single Page Application на фреймах
krapotkin 16.11.2025
Статья исключительно для начинающих. Подходы оригинальностью не блещут. В век Веб все очень привыкли к дизайну Single-Page-Application . Быстренько разберем подход "на фреймах". Мы делаем одну. . .
Фото: Daniel Greenwood
kumehtar 13.11.2025
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru